Link:
Solution:
(1)在这里记录一个小小的黑科技:摩尔投票法
(线性时间复杂度,$O(1)$的空间复杂度求众数)
从数组的第一个元素开始,假定它代表的群体的人数是最多的
设置一个计数器,在遍历时遇到不同于这个群体的人时就将计数器-1,遇到同个群体的人时就+1
只要在计数器归0时就重新假定当前元素代表的群体为人数最多的群体再继续遍历
那么到了最后,计数器记录的那个群体必定是人最多的那个群体
其实就是 抵消的思想嘛,记录当前有可能为众数的数,思想还是不错的
(2)这题还有一个挺妙的算法:记录二进制中每一位出现的次数,最后累加出现次数超过$n/2$的数位
将原数的(个数)关系转化到每一位,好像还挺常用的?
Code:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <bits/stdc++.h> using namespace std; int main() { int n,x,cur=0,cnt=0; scanf("%d",&n); while(n--) { scanf("%d",&x); if(!cnt) cnt++,cur=x; else if(x!=cur) cnt--; else cnt++; } printf("%d",cur); return 0; }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <bits/stdc++.h> using namespace std; int n,x,cnt[35],res; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&x); for(int dgt=0;x;x>>=1,dgt++) if(x&1) cnt[dgt]++; } for(int i=30;i>=0;i--) if(cnt[i]>n/2) res+=(1<<i); printf("%d",res); return 0; }