14Moore's votingArrays and hashing

Moore's voting

Find the value that appears more than half the time, with one candidate and one count.

Clue: find the value that appears more than half the time, with O(1) extra space. Worked example: LeetCode 169, Majority Element (Easy). The pattern is Moore's voting (the Boyer–Moore majority vote algorithm).

The idea

Five friends vote on a drink. Two different votes? Both sit down: they cancel each other out. Same vote? They stand together, and the group grows by one. If over half chose tea, tea is left standing, because each cancel takes away at most one tea.

In code, keep one candidate and one count, the votes left. Same value: count up. Different value: count down. When count is 0, the next value becomes the candidate.

The walk

nums = [2, 1, 1, 3, 1] (2 is coffee, 1 is tea, 3 is juice). Answer: 1.

xcandidatecount
22 (new)1
120 (cancel)
11 (new)1
310 (cancel)
11 (new)1

Each pair takes away at most one 1. There are more 1s than all the rest, so a 1 is left. Quick check from the post: [5, 4, 4] gives candidate 4: 5 and the first 4 cancel, count is 0, so the last 4 becomes the candidate.

Pseudocode

Pseudocode · any language
function majorityElement(nums):
    candidate = none
    count = 0
    for each x in nums:
        if count == 0:
            candidate = x   // new candidate
        if x == candidate:
            count = count + 1
        else:
            count = count - 1
    return candidate

The trap: no majority? You still get a candidate. [1, 2, 3] returns 3, but 3 appears once, which is not over half. When a majority is not promised, count the candidate once more and return it only if it appears more than floor(length(nums) / 2) times; otherwise there is none. LeetCode 169 promises a majority, so it skips this check. Each file below has both versions: majorityElement (LeetCode 169) and majorityOrNone (with the check).

Code

public class Main {
    // LeetCode 169: a majority is guaranteed to exist.
    static int majorityElement(int[] nums) {
        int candidate = 0;
        int count = 0;
        for (int x : nums) {
            if (count == 0) {
                candidate = x;
            }
            if (x == candidate) {
                count = count + 1;
            } else {
                count = count - 1;
            }
        }
        return candidate;
    }

    // No guarantee: count the candidate again. Returns null when there is no majority.
    static Integer majorityOrNone(int[] nums) {
        if (nums.length == 0) return null;
        int candidate = majorityElement(nums);
        int seen = 0;
        for (int x : nums) {
            if (x == candidate) seen = seen + 1;
        }
        return seen > nums.length / 2 ? candidate : null;
    }
}

Complexity

  • Time: O(n). One pass for LeetCode 169; two passes with the check.
  • Extra space: O(1), just candidate and count. (A hash map of counts also takes O(n) time but O(n) space; sorting takes O(n log n).)

How it was tested

All four versions were compiled and run on the same 3,015 inputs (3,000 random arrays of length 0 to 12, half of them forced to have a majority, plus edge cases: empty, single element, all equal, no majority, sorted, reversed, values at ±10^9, and a 100,001-element array) and compared with a brute-force counter. Zero mismatches. Re-run on 31 October 2026 on 3,004 more inputs (3,000 random arrays of length 0 to 12, about half with a majority, plus the example, the quick check, the trap input and the empty array): all four matched on every one.

Practice

Try these in order. Open the worked example first if you got stuck on the slides.