一个数组a[0...n-1],O(n)时限,算出现次数大于n/2的那个数b。
由于b占一半以上,初步思想就是每次都让两个数相互删去,最后就留下b了。
每次至少删掉当前数组一半的数,1+1/2+1/4+...=2,复杂度2n
具体:
每次让第1\2个数比较,相同就留一个,不同就都删掉,如果数组的个数是奇数,最后一个先留着,叫res,这个res有用。
然后求新的数组。如果新的数组全都两两消掉了,说明上一次求的res就是b,如果最后消不掉刘了个新的res,res‘,则res’是b(反正,如果把算法想成一个递归,我们求的b就是递归最底层的res)
int majorityElement(int num[], int n) {
if(n==1) {
return num[0];
}
int cnt=0,pt=0;
int res=0;
int odd = 0;
while(cnt<n) {
if(cnt+1==n) {
res = num[cnt];
odd = 1;
break;
}
if(num[cnt]==num[cnt+1]) {
num[pt++]=num[cnt];
}
cnt+=2;
}
if(pt) {
int ret = majorityElement(num, pt);
if(ret == -0x7fffffff && odd) {
return res;
}
return ret;
} else {
if(odd) {
return res;
}
return -0x7fffffff;//用-inf表示数组两两消去其实不严谨,怕麻烦
}
}