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)个候选。

  • 相关阅读:
    G++ 中文使用教程[转]
    PreparedStatement是如何大幅度提高性能的[转]
    .net 2.0(c#)下简单的FTP应用程序
    Remoting服务集成到IIS的简单总结
    转:xml一些知识
    [翻译]简单谈谈事件与委托 (转)
    觉得不错
    winform的一些知识
    xml 基本语法
    简单的信息采集程序示例(小偷程序) (转)
  • 原文地址:https://www.cnblogs.com/diegodu/p/4670687.html
Copyright © 2011-2022 走看看