找出数组中出现次数大于n/2次的元素。
1.先排序,处于中间n/2处的元素必然是要求的元素,道理很简单,就算把其他元素全放在前半部分或者后半部分也都会占不满的,中间的永远是majority element;
2.暴力,把每个元素出现次数记录下来,一旦大于n/2,就结束。由于每次都要与之前遍历过的元素进行比较,时间复杂度为O(n2);
3.分治,每出现两对不同的数就全部舍弃,这样到最后必然剩下的只会是majority element。但是一般实现复杂度还是比较高。巧妙实现见moore voting algorithm;
4.Moore voting algorithm,这个算法是美国一个大学教授发明的。主要思想是采用一个计数器counter和一个候选元素candidate,有两种情况:一是当counter为0时,将当前元素设为candidate,counter加1,起始这样设置秀好理解,中途这样做是因为counter如果是减到0的,那么就意味着之前的元素全部都两两相抵消了;二是当candidate与当前遍历元素相同就counter加1,不同就减1,减1的道理也是相当于两两抵消了一对不同的元素。最后的candidate就是Majority element。仔细想想这个算法,其实也就是分治法两两抵消不相同元素的一种良好实现,通过counter和candidate实现了分治法的从相邻元素的两两抵消推广到了不相邻元素的两两抵消了。牛!
代码:
1 int majorityElement(int num[], int n) { 2 int counter=0; 3 int candidate; 4 int i; 5 for(i=0; i<n; i++) 6 { 7 if(counter == 0) 8 { 9 counter++; 10 candidate = num[i]; 11 } 12 else if(num[i] == candidate) 13 { 14 counter++; 15 } 16 else 17 { 18 counter--; 19 } 20 } 21 return candidate; 22 }