《编程之美》寻找发帖水王扩展问题的代码实现

来源:互联网 发布:极光数据恢复软件官网 编辑:程序博客网 时间:2024/05/16 02:25

    求职过程中,你会发现面试官的不少问题在《编程之美》中都能找到痕迹。想在企业招聘面试中成功忽悠,这本书不可不读。算了,不再打广告了,哈哈。

    书中有一节探讨了“寻找发帖水王”,问题是从一堆ID构成的集合中,找到某个发帖总数超过帖子总数一半的ID。面试中的常见问题“从一堆整数中找到出现次数超过总数一半的整数”实际上就是该问题了。

    在原题中,初步解法是对所有的ID进行排序,然后分析可知这个有序表中第N/2项便是问题的解,这个思路时间复杂度是O(N*log2N)。

    改进的思路中不再对这些ID排序了,而是每次从ID列表中删除两个不同的ID,不断重复这个过程,直到遍历完所有的ID,此时要找的ID就出现啦,总的时间复杂度O(N)。该思路通过将原始问题逐步转化为规模较小的子问题,但是问题的解保持不变。

    后面给出了一个扩展题:有三个ID的发帖数目都超过了帖子总数目的1/4,要求我们找出这三个ID。方法是类似的,即每次从ID列表中删除4个不同的ID,不断重复这个过程,最后即可得到这三个ID。

    解决的思路:用数组candidate和count分别存储三个不同的疑似ID及其累计出现次数。遍历存储ID的数组,如果candidate数组中存在某个元素为空,则将当前遍历到的ID存进去;如果candidate中已经存储了三个不同的疑似ID,则将当前遍历到的ID与它们对比。对比的过程是,如果candidate中有某个ID与之相等,则将对应的count加1,否则将count中的所有元素都减1。

    哎,认认真真写篇博客真费劲,好了,下面是贴代码的时候了,测试了部分数据,答案木有问题。如果有啥问题,欢迎提出交流哈。

#include<iostream>using namespace std;int candidate[3]={0},count[3]={0};int findzero() // 遍历count数组,返回第一个为0的元素的index,如果没有0则返回-1{for(int i=0;i<3;i++)if(count[i]==0)return i;return -1;}void find(int id[],int n){for(int i=0;i<n;i++){int fz=findzero();if(fz>=0) // 表示count数组中有0元素,则存下当前的id{candidate[fz]=id[i];count[fz]++;}else // 表示candidate数组中已经存在3个不同的元素{bool tag=false;    // 表示当前的id和candidate中的3个id不等for(int j=0;j<3;j++)if(candidate[j]==id[i]){count[j]++; tag=true;continue;}if(tag==false){for(int j=0;j<3;j++)count[j]--;}}}}int main(){int a[50],num;cout<<"please input the number of IDS: ";cin>>num;cout<<"please input all the IDs: ";for(int i=0;i<num;i++)cin>>a[i];find(a,num);cout<<"They are "<<candidate[0]<<" "<<candidate[1]<<" "<<candidate[2]<<endl;system("pause");return 0;}


 

0 0
原创粉丝点击