”水王“问题

原创 2013年12月04日 22:10:40

来自编程之美

方法一:sort,第n/2个数必定是那个数;

fast select,选择第n/2个数;


方法二:

int Find(int *id,int N)
{
    int candidate;
    int nTimes,i;
    for(i=nTimes=0;i<N;i++)
    {
        if(nTimes==0)
        {
             candidate=id[i];
             nTimes=1;
        }
        else
        {
             if(candidate==id[i])
                 nTimes++;
             else
                 nTimes--;
        }
    }
    return candidate;
}

扩展1:找出正好出现一半的那个数

int Find(int* a, int N)  
{  
    int candidate1,candidate2;  
    int nTimes1, nTimes2, i;  
          
    for(i = nTimes1 = nTimes2 =0; i < N; i++)  
    {  
        if(nTimes1 == 0)  
        {  
            candidate1 = a[i], nTimes1 = 1;  
        }  
        else if(nTimes2 == 0 && candidate1 != a[i])  
        //注意:这里的判断条件加上第二个变量是否等于第一个变量的判断  
        {  
              
            candidate2 = a[i], nTimes2 = 1;  
        }  
        else  
        {  
            if(candidate1 == a[i])  
                nTimes1++;  
            else if(candidate2 == a[i])  
                nTimes2++;  
            else  
            {  
                nTimes1--;  
                nTimes2--;  
            }  
        }  
    }  
    return nTimes1>nTimes2?candidate1:candidate2;  
}  


扩展2:如果论坛发帖ID列表中,有三个发帖很多的ID,他们的发帖数目都超过了帖子总数N的1/4,你能快速找到它们吗?

void find3(int a[],int ret[],int n)
{
    int cnt[3] = {0};
    int i,j,k;

    ret[0] = ret[1] = ret[2] = INT_MIN;
    for(i = 0; i < n;i++)
    {
        for(j = 0; j < 3;j++)
            if(ret[j] == a[i])
            {
                cnt[j]++;
                break;
            }
        if(j == 3)
        {
            for(k = 0; k < 3;k++)
                if(cnt[k] == 0)
                {
                    cnt[k] = 1;
                    ret[k] = a[i];
                    break;
                }
            if(k == 3)
                cnt[0]--,cnt[1]--,cnt[2]--;
        }
    }
}



相关文章推荐

编程之美 寻找发帖水王 扩展问题

编程之美中的“寻找发帖水王”描述的是这么一个问题,有一个ID列表,其中有一个ID(水王的ID)出现的次数超过了一半,请找出这个ID。 书中的思路是每次从列表中删除两个不同的ID,不影响“水王的ID在...

寻找发帖水王问题总结

题目是这样描述的:“水王”发帖的数目超过了所有帖子的一半,有各个帖子的作者ID,求这个水王的ID 编程之美给出了两种巧妙的解法 解法一:ID排序,那么ID列表中的N/2项即为要找的ID(还要排序,...
  • ysu108
  • ysu108
  • 2012年04月14日 09:14
  • 8156

微软《编程之美》:寻找发贴“水王” 及 其扩展问题

原始问题 Tango是微软亚洲研究院的一个试验项目。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“...

倒水问题的解答

  • 2014年03月20日 18:39
  • 3KB
  • 下载

分水问题--容器法

  • 2008年04月14日 23:20
  • 4KB
  • 下载

猴子选大王(约瑟夫环问题)两种解决方案

问题: 有M只猴子围成一圈,按序每只从1到M中的编号,打算从中选出一个大王;经过协商,决定出选大王的规则:从第一个开始循环报数,数到N的猴子出圈,最后剩下来的就是大王。要求:从键盘输入M、N,编...
  • cai0538
  • cai0538
  • 2011年11月17日 11:19
  • 5198

组态王n个经典问题解答.

  • 2010年05月05日 17:13
  • 77KB
  • 下载

求数组中出现次数超过一半的元素(《编程之美》寻找水贴王问题)C代码

给定一个数组,其中有一个元素的出现次数超过1/2,如何快速的找出这个元素。这个问题在《编程之美》中是这样描述的: “研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水...

组态王的N个经典问题

  • 2013年04月24日 09:41
  • 138KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:”水王“问题
举报原因:
原因补充:

(最多只允许输入30个字)