剑指 Offer 39. 数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
概述
本题常见的三种解法:
哈希表统计法: 遍历数组 nums ,用 HashMap 统计各数字的数量,即可找出 众数 。此方法时间和空间复杂度均为 O(N) 。
数组排序法: 将数组 nums 排序,数组中点的元素 一定为众数。
摩尔投票法: 核心理念为 票数正负抵消 。此方法时间和空间复杂度分别为 O(N) 和 O(1) ,为本题的最佳解法。
摩尔投票
假设第一个数字为众数,后续遍历过程中,相同votes+1,不同votes-1,若未遍历到底votes就=0,则重新选取幸运儿下一个元素为众数,继续执行相同的操作,直到遍历完成,votes>0的话,选取的众数就是结果。
class Solution {
public:
int majorityElement(vector<int>& nums) {
int votes = 0, a;
for(auto num : nums){
if(votes == 0) a = num;
votes += num == a ? +1 : -1;
}
return a;
}
};
哈希
class Solution {
public:
int majorityElement(vector<int>& nums) {
unordered_map<int, int> mp;
for(auto num : nums){
mp[num]++;
if(mp[num] > nums.size() / 2) return num;
}
return -1;
}
};