先放上一道leetcode原题
如果我们想找到这个多数元素,可以有很多方法:
1.像暴力二重循环,不过O(N²)的算法肯定不是理想的算法;
2.一般的解法应该是使用哈希表(hash_map) ,存储键值对结构,每次遇到一个数key,
如果map里没有就插入,如果有就把其出现次数value+1;最后我们遍历map找到最大的value,返回key,这样我们可以得到一个时间复杂度O(N),空间复杂度O(N)的算法,但是题目告诉我们还有空间复杂度O(1)的算法,我们看看是什么玩意。
摩尔投票法可以简单理解成不同元素相互抵消
数组里有一个元素——多数元素,这个元素出现次数大于 数组大小除以二向下取整,即出现次数超过数组大小的一半,那么数组中不同元素两两抵消,最后剩下的必定都是多数元素,至少剩一个。
例如[ 3,3,6,6,5,3,6,5,3,3] 最后剩[3,3]
[3,5,6,3,2,3,3] 最后剩[3]
基于这种想法,我们可以不存储元素出现的次数,只用到有限几个变量
int majorityElement(vector<int>& nums) {
//摩尔投票法
int x = nums[0];
int count = 1; //count变量代表当前元素x还有多少个没和其他元素抵消,一开始为1
for(int i = 1; i < nums.size() ;i++)
{
//如果x元素还有剩,且新到达元素等于x,count+1
if(count != 0 && x == nums[i])
{
count++;
}
//如果x元素还有剩,且新到达元素可以和x抵消,count-1
else if(count != 0 && x != nums[i])
{
count--;
}
else //x元素已经抵消完,新到达元素成为x,count = 1
{
x = nums[i];
count = 1;
}
}
return x;
}