Problem: 169. 多数元素
遍历
遍历整个数组,对记录每个数值出现的次数(利用 HashMap,其中 key 为数值,value 为出现次数);
接着遍历 HashMap 中的每个 Entry,寻找 value 值> nums.length / 2 的 key 即可。
排序
数组中有出现次数超过一半的元素,则排好序之后的数组中,超过一半的元素总会占据队中位置。
例如:1 2 1 2 1在排序后成为 1 1 1 2 2,则返回队中元素即可。
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(),nums.end());
return nums[nums.size()/2];
}
};
摩尔投票
遍历选取候选人cand_num,候选人的票数记为count。
票数 count 初始化为 1。
当遇到与 cand_num 相同的数,则票数 count = count + 1,否则票数 count = count - 1。
当票数 count 为 0 时,更换候选人,并将票数 count 重置为 1。
遍历完数组后,cand_num 即为最终答案。
为何这行得通呢?
因为我们需要得到投票>一半的获胜者,假设共有2n个选票,n+1个人选了同一个人,n-1个人选了其他人,用n+1和n-1进行两两碰撞抵消,最终剩余的就是获胜者。
将票数+1看做统计,票数-1看做碰撞;
投票法是遇到相同的则 票数 + 1(统计),遇到不同的则 票数 - 1(碰撞)。
且“多数元素”的个数 > ⌊ n/2 ⌋,其余元素的个数总和 <= ⌊ n/2 ⌋。
因此“多数元素”的个数 - 其余元素的个数总和 的结果 肯定 >= 1。
这就相当于每个 “多数元素” 和其他元素 两两相互抵消,抵消到最后肯定还剩余 至少1个 “多数元素”。
例:无论数组是 1 2 1 2 1,亦或是 1 2 2 1 1,总能得到正确的候选人。
int majorityElement(int[] nums) {
int ret = 0;
int counter = 0;
for (int i = 0; i <= nums.length - 1; i++) {
if (counter == 0) {
ret = nums[i];
counter = 1;
} else if (nums[i] == ret) {
counter++;
} else {
counter--;
}
}
return ret;
}