题目:已知长度为n的数组中有一个出现次数>n/2的数字,求这个数字
分析:
第一眼的想法就是记录下出现的每个不重复数字,然后统计每个数字出现的次数,复杂度n*n,也是暴力啊
然后想到的就是随机抽一个数字,判断它出现的次数是否>n/2,毕竟是众数容易抽到,期望复杂度是2*n
还有一个容易想到的方法就是开一个长度> max(array)的数组mark,扫描一遍array,将对应下标的mark++,最后mark中具有最大值的下标就是答案。复杂度是n+max(array)
最后牛笔的大神还想到了一个方法就是投票法。定开头元素为candidate,然后扫描数组,统计count。若当前元素和candidate不一致,count--,否则count++。若count小于0,淘汰candidate,将当前元素选为新的candidate。扫描完之后的candidate就是答案了。这个模糊一想觉得还挺有道理,但是不知道数学证明应该怎样。
补充:现在一想感觉还是挺容易的,因为众数的数目大于一半,所以肯定能在投票中获胜。反过来,假设一个非众数在投票中取胜了,那么它获得的投票至少要比众数多,这样才能减完后>0成为胜利者,这和众数的投票矛盾了,所以肯定不行。
答案:
class Solution {
public:
int majorityElement(vector<int> &num) {
int candidataNum = num[0];
int voteCount = 0;
for( int i = 0; i < num.size(); i++)
{
if (num[i] == candidataNum)
voteCount ++;
else
{
voteCount --;
if (voteCount < 0)
{
candidataNum = num[i];
voteCount = 1;
}
}
}
return candidataNum;
}
};