zoukankan      html  css  js  c++  java
  • 查找出现次数大于n/k的重复元素

    本文是对一篇英文论文的总结:Finding Repeated Elements。想看原文,请Google之。

    这个问题的简单形式是“查找出现次数大于n/2的重复元素”。我们先从简单问题开始,然后再做扩展。

    1.查找出现次数大于n/2的重复元素

      《编程之美》中有同样的一道题《寻找发帖水王》,具体思路是每次删除两个不同的元素,最后剩下的就是要求的元素。这个结论的证明如下:

      已知:n,m是正整数,n表示数组的长度,m是出现次数大于n/2的元素的个数,即m>n/2。

      需要求证的结论包括两个:

     (1)我们用v表示出现次数大于n/2的元素。当删除两个不同元素,且其中有一个元素是v时,则m减小1,同时n要减小2。

      求证:m-1>(n-2)/2    

      证明:m-1>n/2-1=(n-2)/2

     (2)当删除两个不同元素,且其中有一个元素不是v时,则只需要n减小2。

      求证:m>(n-2)/2 。这个结论是显然的。

    代码如下:

    int find(int array[], int n)
    {
        int candidate;
        int count=0;
        for(int i=0;i<n;++i)
        {
            if(count==0)
            {
                 candidate=array[i];count=1;
            }
            else
            {
                 if(candidate==array[i])
                       ++count;
                  else 
                       --count;   
            }       
        }  
        return candidate;
    }

    上述代码是错误的,最后还要验证一下candiate是不是的出现次数是大于n/2的。反例,1,2,3,最后剩下的是3,但是他不是我们要的结果。

    《编程之美》的后面习题是“查找出现次数大于n/4的元素”,思路是每次删除不同的4个元素,最后剩下的3个就是候选元素,但是还要验证这3个元素是否满足条件。不再详细解释。其实《编程之美》里讲的方法就是本文后提到的“多重集”算法。

    对于大于n/4的元素,最多有3个候选人,我们就设置3个candidate,每次同时删掉4个元素,其实是3个candidate同时减1。对剩下的3个元素检验是否是我们想要的结果即可。

    推广到找到大于n/k的情况,设置(k-1)个候选。

  • 相关阅读:
    python 冒泡排序
    python链式调用REST API把参数放到URL中
    python assert断言用法
    python实现斐波那契数列
    Pycharm快捷键集合
    linux shell中$0,$?,$!等的特殊用法
    搭建邮箱服务器
    linux安装IB驱动方法
    Oracle:Redhat 7.4+Oracle Rac 11.2.0.4 执行root.sh报错处理
    Struts学习(一)
  • 原文地址:https://www.cnblogs.com/diegodu/p/4670687.html
Copyright © 2011-2022 走看看