固定宽度范围内最常见的元素 - 线性时间

时间:2014-04-25 08:51:27

标签: performance algorithm language-agnostic

问题:

我有一个N个整数的数组A.对于每个i(i

每个元素A [i]介于0和10000之间 但是N <= 5 * 10 6 且M <= 5 * 10 5

我的解决方案:

我有一个O(N log 2 (max(A [i]))解决方案:

创建一个二进制堆,存储每个值的出现次数,并在移动到下一个M元素时适当地更新它。

我需要一个更快的解决方案,这需要时间线性的N,元素的数量。


我看过this question这与我的非常相似,但约束较低,所讨论的解决方案还不够快。

另一个question与我的相似,但解决方案假设A [i]最多有128个值。

我也看过这里讨论过的其他类似问题,但似乎没有一个问题对我有用。

1 个答案:

答案 0 :(得分:1)

您可以使用专门的堆来获得线性时间。这个堆只不过是链接列表的(M + 1)元素数组。索引k处的链表由在当前窗口中出现k次的元素组成。要增加元素的数量,请将其从当前列表中删除,然后将其插入到更高的元素中。检查此元素现在是否最常见。要减少元素的数量,请将其从当前列表中删除,然后将其插入到较低的元素中。通过检查以前的列表,检查这个元素是否不再是最常见的。

在C中,所需的结构可以这样声明。

struct Node {
    struct Node *prev, *next;
    long freq;
    int value;
} g_element[10000 + 1];

struct Node g_list_head[500000 + 1];

struct Node *g_most_freq;