一、定义
摩尔投票是一种用来解决绝对众数问题的算法。
在一个集合中,如果一个元素的出现次数比其他所有元素的出现次数之和还多,那么就称它为这个集合的绝对众数。等价地说,绝对众数的出现次数大于总元素数的一半。
二、使用案例
function majorityElement(nums: number[]): number {
let candidate:number = NaN; // 候选者
let cnt:number = 0; // 票数
for(let num of nums) {
if(cnt == 0) candidate = num;
num == candidate ? cnt++ : cnt--;
}
return candidate;
};
majorityElement([2,2,1,1,1,2,2]);
具体分析:
摩尔投票维护两个变量,一个是候选者,一个是票数,当前候选者继续有人为其投票时,票数加一,为别人投票时,票数减一。当票数减为 0 时,说明前面没有任何人有优势,那么候选者为下一个被投票的人。
那么为什么,绝对众数 的人可以获胜呢?
因为可以绝对众数的票,平均分配给每一票,局面变成
[ 2, 1, 2, 1, 2, 1, 2 ]
无论中间是什么数,最后一定会剩下一个 2,让它稳赢成为胜利者
所以即便,票数分布是不均匀的,那么肯定会使 2 也会扎堆存在,最后使得 cnt 变量大于等于 1,而 2 肯定是最后的胜利者
借用一句话:是金子总会发光
三、其他解法
这道题,还有一个更直接的解法是,直接排序,由于 绝对众数 的数量大于总数的二分之一,那么中间位置必然是所要求的 绝对众数。
function majorityElement(nums: number[]): number {
nums.sort();
return nums[Math.floor(nums.length / 2)];
};