如何找到重复至少N/2次的数组元素?

Fla*_*ash 34 c algorithm

给定一个包含N个元素的数组.我们知道其中一个元素至少重复N/2次.

我们对其他元素一无所知.它们可能重复或可能是唯一的.

有没有办法找出在一次通过中重复至少N/2次的元素,或者可能是O(N)?

没有额外的空间可供使用.

Nab*_*abb 56

由于其他用户已经发布了算法,我不再重复了.但是,我提供了一个简单的解释,说明它的工作原理:

考虑下图,它实际上是非偏振光的图表:

从中心辐射的箭头

来自中心的每个箭头代表不同的候选者.想象一下箭头上的某个点代表计数器和候选人.最初计数器为零,因此它从中心开始.
当找到当前候选者时,它向该箭头方向移动一步.如果找到不同的值,则计数器向中心移动一步.
如果存在多数值,则超过一半的移动将朝向该箭头,因此算法将以当前候选者为多数值结束.


Dav*_*nco 37

st0le回答了这个问题,但这是一个5分钟的实现:

#include <stdio.h>

#define SIZE 13

int boyerMoore(int arr[]) {
    int current_candidate = arr[0], counter = 0, i;
    for (i = 0; i < SIZE; ++i) {
        if (current_candidate == arr[i]) {
            ++counter;
            printf("candidate: %i, counter: %i\n",current_candidate,counter);
        } else if (counter == 0) {
            current_candidate = arr[i];
            ++counter;
            printf("candidate: %i, counter: %i\n",current_candidate,counter);
        } else {
            --counter;
            printf("candidate: %i, counter: %i\n",current_candidate,counter);
        }
    }
    return current_candidate;
}

int main() {
    int numbers[SIZE] = {5,5,5,3,3,1,1,3,3,3,1,3,3};
    printf("majority: %i\n", boyerMoore(numbers));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是一个有趣的解释(比阅读论文更有趣,至少):http://userweb.cs.utexas.edu/~moore/best-ideas/mjrty/index.html

  • 该算法满足问题的条件.但是,应该记住它返回潜在的多数项目.如果没有多数,则结果毫无意义.因此,如果您不确定,则必须再次循环,并查看该元素实际出现的次数. (6认同)
  • 这个问题假设"我们知道其中一个元素重复*至少*N/2次",所以如果数据格式良好,算法每次都会有效. (3认同)

st0*_*0le 36

Boyer-Moore多数投票算法

//list needs to have an element with a count of more than n/2 throughout itself for
//this algorithm to work properly at all times.

lst = [1,2,1,2,3,1,3,3,1,2,1,1,1]

currentCount = 0
currentValue = lst[0]
for val in lst:
   if val == currentValue:
      currentCount += 1
   else:
      currentCount -= 1

   if currentCount == 0:
      currentValue = val
      currentCount = 1


print(currentValue)
Run Code Online (Sandbox Code Playgroud)