Moore voting method (majority voting method)

Moore voting: The main problem to be solved is how to choose the one with the most votes among any number of candidates (the ballots are out of order).

时间复杂度:O(N)
空间复杂度:O(1)

Visual description:
Insert picture description here

Imagine a picture like this: the conference hall is full of voting representatives, each with a sign with the name of the candidate of their choice. Then the two people who disagree with each other (the selected candidates are different) will fight and knock down each other at the same time. Obviously, if one person has more votes than all the other votes combined, the candidate will win the "war", and when the chaos ends, the last remaining representative (there may be more than one) Will come from the camp where most people stand. But if the votes of all the candidates are not a majority (no more than half of the votes), then the representative (one person) who stands there last cannot represent the majority of all the votes. Therefore, when a person stands at the end, it is necessary to count whether the votes of the candidate he selected are more than half (including the fallen ones) to determine whether the result of the ballot is valid.

Algorithm steps:

It is divided into two stages: the pairing stage and the counting stage. The
confrontation stage: two people with different votes will fight against each other and knock down each other at the same time. When the rest of the people are in the same camp, that is, the same vote ,the end.
Counting stage: Count the votes of the last remaining people to determine whether the votes are more than half of the total votes and whether the votes are valid.

Simplification of the confrontation phase:
Insert picture description here
We do not need to have different votes to fight , we can take a more civilized approach. There was a very smart person present. He scanned all the votes and remembered two things in his mind. The current candidate’s name cand and his corresponding counter k (k is initialized to 0, not cand’s Number of votes). When looking at everyone’s votes, first check whether k is 0. If it is 0, update cand to the name of the candidate he saw immediately, and update the value of k to 1. At this time, k represents It is the number of camps after the cand update. Observe the process of each person’s vote. If the person’s vote is the same as cand, then the value of k is set to +1, otherwise, the value of k is set to -1, and the final cand may win the election. It is also necessary to count whether his total number of votes exceeds half.

Algorithm proof:

Insert picture description here
Suppose there are n representatives (one person, one vote, and the total number of votes is n). When a smart person sees the votes of the i-th representative (1 ≤ i ≤ n ), all the votes he has seen before can be divided into two groups, the first group is k representatives agree to cand; the other group is the votes can All offsets in pairs (different votes). When all the votes are processed, if there is a majority, cand is elected.
Suppose there is an x ​​which is different from cand, but has more than n/2 votes. But because the votes of the second group can all be offset in pairs, the number of votes with the largest number of x is (n − k) / 2, so x must receive the first group of votes to exceed half, but the first group of votes They are all cand, there are contradictions, and the hypothesis does not hold.
So, if there is a majority, cand is that one.

Algorithm demo:
web link

Code framework:

    public int majorityElement(int[] nums) {
    
    
        int cand = 0, k = 0;
        //对抗阶段,最后的cand有可能就是选票最多的候选人
        for (int i = 0; i < nums.length; i++){
    
    
            if(k == 0){
    
    
                cand = nums[i];
                k = 1;
            }
            else {
    
    
                if(nums[i] == cand){
    
    
                    k += 1;
                }
                else {
    
    
                     k--;
                }
            }
        }
        //计数阶段,看是否是大多数
        int cnt = 0;
        for (int num:nums) {
    
    
            if(num == cand)
                cnt++;
        }
        //表示未超过一半
        if (cnt <= nums.length/2){
    
    
            cand = -1;
        }
        return cand;
    }

Guess you like

Origin blog.csdn.net/Puppet__/article/details/115296697