刷题过程中遇到的一个非常巧妙的算法。是出现在“求数组中出现超过一半的数字”这道题中。
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
实例1
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
1 <= 数组长度 <= 50000
思路:如果把数组中的众数(即题目中的出现超过一半的数字)记为1,把其他数记为-1,再把它们全部加起来,显然和应该大于0,这是因为这道题的特点是众数超过了总数的一半。基于这个规律,可以设计一个算法:我们选择第一个数作为候选众数,并维护一个计数器,初始令计数器等于1,。然后往后遍历数组,如果遇到当前的候选众数,就将计数器加一,否则将计数器减一。只要计数器等于0,我们就选择下一个数作为新的众数,并将计数器重新置为1,这样最终得到的这个数就是超过数组半数的众数。
class Solution {
public:
int majorityElement(vector<int>& nums) {
int count = 0;
int candidate = 0;
for (int i : nums){
if (count == 0){
candidate = i;
count++;
}
else if (candidate == i){
count++;
}
else{
count--;
}
}
return candidate;
}
};