【编程之美学习笔记】2.3寻找发帖水王坊间风闻“水王”发帖数目超过帖子总数的一半,如果你有一个当前论坛上所有帖子的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的水王吗?

题意即找出数组中超过一半的数

最直接的方法是对所有ID排序,然后再扫描一遍排好的ID列表,统计各个ID出现的次数,若某个ID次数超过总数的一半则输出这个ID,这个算法的时间复杂度为O(N * log2N + N)。

但事实上,若ID列表有序,不必再次扫描列表。若一个ID出现的次数超过总数N的一半,那么这个有序的ID列表中的第N/2项(从0开始编号)一定会是这个ID。这样能迅速定位到列表的某一项的话(比如用数组),该时间复杂度为O(N * log2N )。

但上面两种方法都要先对ID列表进行排序,时间复杂度方面没有本质的改进,能否避免排序呢?

如果每次删除 2 个不同的ID(不管是否包含“水王”的ID),那么在剩下的ID列表中,“水王”的ID出现的次数仍然超过总数的一半。可以通过不断重复这个过程把ID列表中的ID总数降低(转化为更小的问题),从而得到答案。

这个思路,避免了排序这个耗时的步骤,总的时间复杂度只有O(N),且只需要常数的额外内存。

 1 Type Find(Type *ID, int N){
 2     Type candidate;
 3     int nTimes, i;
 4     for(i = nTimes = 0; i < N; i++){
 5         if(nTimes == 0){
 6             candidate = ID[i], nTimes = 1;
 7         }
 8         else{
 9             if(candidate == ID[i])
10                 nTimes++;
11             else
12                 nTimes--;
13         }
14     }
15     return candidate;
16 }
View Code

相关文章:

  • 2021-08-11
  • 2022-12-23
  • 2021-09-23
  • 2021-12-01
  • 2022-03-02
  • 2021-12-01
猜你喜欢
  • 2021-12-01
  • 2021-12-01
  • 2021-09-11
  • 2022-12-23
  • 2021-12-01
  • 2021-08-22
相关资源
相似解决方案