【问题标题】:Is there an efficient way to find the most frequent number in a sorted array of ranges in constant space有没有一种有效的方法可以在恒定空间的有序范围数组中找到最频繁的数字
【发布时间】:2021-07-14 18:35:12
【问题描述】:

我必须从排序的范围数组中找到最频繁的数字(或模式)。此范围仅由包含的开始和结束编号组成。 例如,arr[0] 可以包含数字 {0, 3},这意味着数字 {0, 1, 2, 3}。范围按起始编号排序,当起始编号相等时,它们按结束编号排序。两者都按升序排列。

数组中填充了 n 个这些范围。我需要找到一种方法来找到出现在最多范围内的数字。

我想到了一个解决方案,它遍历所有数字一次,但这是在 O(n * m) 中,其中 m 是范围的平均长度。对于我正在处理的大小,这是一个非常慢的算法。

我还研究了一些更快的解决方案,例如this,但是当您无法轻松找到第 k 个数字时,我想不出一种有效的方法来实现它,因为范围的大小可能大相径庭。

我目前正在尝试在 C 中实现这一点,但非常感谢任何想法或与此相关的资源的链接。

【问题讨论】:

  • 您的问题标题提到了一组 排序 范围。它们是按起始编号还是其他方式排序的?
  • 按起始编号排序,如果起始编号相同,则按结束编号排序。我会将这些信息添加到我的帖子中。
  • 范围可以有多大?最大可以有多少范围?
  • 10^8 范围。每个范围可以在 0 到 2^32 - 1 之间
  • 如果几个数字(不一定是连续的)是最频繁的怎么办?例如,如果没有任何范围重叠,则该范围集中的所有数字仅出现 1 次。

标签: c algorithm frequency


【解决方案1】:
  1. 将每个范围{a, b} 转换为两个事件“a 加 1”和“b+1 减 1”。
  2. 按添加或减去位置的升序对事件进行排序。相同位置的减法事件应该早于添加事件。
  3. 执行事件并检查计算结果在什么时候变得最高。

例如,如果我们有 3 个范围 {0, 5}, {2, 9}, {4, 7},每个范围将是这样的:

0123456789
------
  --------
    ----

排序后的事件是:

  • 0 加 1
  • 2 加 1
  • 将 1 添加到 4
  • 减 1 到 6
  • 减 1 到 8
  • 减 1 到 10

执行这些事件,在执行第3个事件之后,执行第4个事件之前,值变成最高的3。因此,我们可以说出现最多的数字是 4 和 5。

时间复杂度为 O(N log N) 因为:

  • 从范围到事件的 O(N) 转换
  • O(N log N) 事件排序
  • O(N) 次事件执行

存储事件的空间复杂度为 O(N)。

【讨论】:

  • 感谢您的回复。我不明白这种方法是如何工作的。这是否需要我将所有数字存储在某处,如 0,1,2,3,4,5,7,8,9,10 所示,然后将其更新为 1,1,3,3,5, 5,5,7,7,9,9?一个例子将不胜感激。我也问这个问题,因为我们的最大可能范围是 [0, INT_MAX],并且存储所有可能的值可能会占用大量内存。
  • 问题标题暗示空间复杂度需要为O(1)。不过我喜欢你的算法!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-14
  • 2023-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多