问题描述:
Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋
times.
You may assume that the array is non-empty and the majority element always exist in the array.
思路:每找到一个一对不同的数字,都删去,如果这个数大于n/2,那么最后剩余的一定是这个众数。参考代码:
class Solution { public: int majorityElement(vector<int>& nums) { int candidate = 0; int time = 0; for(int i = 0;i < nums.size();++i) { if(time == 0) { candidate = nums[i]; ++time; } else { if(candidate == nums[i]) { ++time; } else { --time; } } } return candidate; } };进一步思考:
这道题有没有其他O(n)的解法呢,答案当然是有的,而且不止一个:
1.哈希表:思路也比较清晰,就是通过哈希表来存储,然后再查找哈希表中出现最多的元素,代码略。
2.位运算:这个方法是看了Solution之后才知道的,这里假设数据值范围为(1,2^32-1),那么我们需要一个32个元素的list,初始值都为0。这里的32表示元素转换成二进制之后的32位数。对于每一位数,遍历数据list里的所有数,记录该位为1的个数。如果个数>=len(num)/2+1,则该位为1,否则为0。同理算出每一位,再转换成10进制数即为出现次数最多的数。
3.随机采样算法:因为题目中告诉了这个数一定会出现,而且出现的次数>=1/2,那么我们可以随机取一个数进行判断。理论上平均两次就可以找到这个数。当然从算法的角度上来看这个算法的最坏情况是infinite(考虑永远都取不到正确数的情况),但对于一个实际问题这个方法还是可行的。
4.moore’s voting 算法:这个算法以前没有听说过,是专门解决这一问题的,给一个链接让大家参考一下: http://http://www.cs.utexas.edu/~moore/best-ideas/mjrty/
具体证明在链接里面也能找得到,内容有点多我也没有细看,有兴趣的朋友可以看看,这里附下代码:
class Solution: # @param num, a list of integers # @return an integer def majorityElement(self, num): currNum = -1 times = 0 for i in range(len(num)): if (times == 0): currNum = num[i] times = 1 else: if (num[i]==currNum): times = times+1 else: times = times-1 return currNum;