算法之摩尔投票法
今天接触了一个很有意思的算法,用于求众数。
用力扣的题做起来比较有感觉,https://leetcode.cn/problems/majority-element/。
当一群人投票表决某一个事时,想找出占人数一半以上的观点可用此方法。
让这群人排好队,一个个的去表明自己的观点。第一个人表达的观点先设置为目标观点,然后请第二个人上来,如果第二个人和第一个人观点一致,则这个观点的支持人数+1。不一致的话-1,当一个观点支持人数为0时,直接废弃。比如上来十个人,五个人支持A观点,其他五个人支持其他观点。那么表示他们十个人就没来过。从第十一个人重新开始。
上面是算法的实现思路,看起来有点绕。通俗的解释是,这群人都是炸弹,遇到相同的观点时他们不会爆炸,但是遇到不同的观点时,他们就带着对方同归于尽。这样剩下来的必定是超过一半人支持的观点。因为最极端的情况是,其他所有观点团结起来进攻这个观点。
比如有个数列7 5 7 5 5 7 7 1 5 7 7
首先选择7,然后5上来,两人同归于尽,接下来上来的两个也同归于尽,数列变成5 7 7 1 5 7 7。这个时候选5作为主流观点,接下来上来两个7,主流观点变成7。然后1上来,这个时候又没有主流观点。重新选择为下一个的5,然后上来两个7,得出答案为7。
这个算法用于求无序的数列遍历一次就可以得出答案,比先排序再找中位数快。
public int majorityElement(int[] nums) {
int count =0;
int res = 0;
for(int i=0;i<nums.length;i++) {
if(count==0) {
res = nums[i];
}
if(nums[i]==res) {
count++;
}else {
count--;
}
}
return res;
}