Majority Element II

Medium Arrays & Hashing Moore's Voting Algorithm Original on LeetCode

Majority Element II is a medium arrays & hashing problem solved with the moore's voting algorithm pattern. The best approach, optimal (boyer–moore with two candidates), runs in O(n) time and O(1) space. Below are 2 approaches in Java, from brute force (hash map count) up.

Problem

Given an integer array nums of size n, return every value that appears more than n / 3 times, in any order.

Follow-up: can you do it in linear time and constant extra space?

Examples

Example 1

Input
nums = [4, 1, 4, 2, 1, 4, 1]
Output
[4, 1]
Why
n = 7, so the threshold is more than 2. Both 4 and 1 appear 3 times.

Example 2

Input
nums = [1, 2, 3]
Output
[]

Constraints

  • 1 <= nums.length <= 5 * 10^4
  • -10^9 <= nums[i] <= 10^9

Animated walkthrough

A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.

Concepts first, then the problem and every approach, step by step.

Space to play or pause · ← → to jump a step · click or drag the bar to seek

Solutions

Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.

ApproachTimeSpace
Brute force (hash map count)O(n)O(n)
Optimal (Boyer–Moore with two candidates)O(n)O(1)

1Brute force (hash map count)

TimeO(n)One counting pass and one pass over the map.
SpaceO(n)Up to n distinct keys.

Count every value and keep the ones whose count is above n / 3.

  1. Count occurrences in a map.
  2. Collect keys with count > n / 3.
Java
class Solution {
    public List<Integer> majorityElement(int[] nums) {
        Map<Integer, Integer> count = new HashMap<>();
        for (int x : nums) count.merge(x, 1, Integer::sum);
        List<Integer> out = new ArrayList<>();
        for (Map.Entry<Integer, Integer> e : count.entrySet())
            if (e.getValue() > nums.length / 3) out.add(e.getKey());
        return out;
    }
}

2Optimal (Boyer–Moore with two candidates)

TimeO(n)Two linear passes.
SpaceO(1)Four variables.

At most two values can appear more than n / 3 times. Keep two candidates with two counters: a match adds a vote, a value matching neither cancels one vote from both. Survivors are only candidates, so count them again to confirm.

  1. Track c1, n1 and c2, n2.
  2. If x equals c1 or c2, increment that counter.
  3. Else if a counter is 0, make x that candidate with count 1.
  4. Else decrement both counters.
  5. Second pass: count c1 and c2 and keep those above n / 3.
Java
class Solution {
    public List<Integer> majorityElement(int[] nums) {
        int c1 = 0, c2 = 1, n1 = 0, n2 = 0;
        for (int x : nums) {
            if (x == c1) n1++;
            else if (x == c2) n2++;
            else if (n1 == 0) { c1 = x; n1 = 1; }
            else if (n2 == 0) { c2 = x; n2 = 1; }
            else { n1--; n2--; }
        }
        n1 = 0; n2 = 0;
        for (int x : nums) {
            if (x == c1) n1++;
            else if (x == c2) n2++;
        }
        List<Integer> out = new ArrayList<>();
        if (n1 > nums.length / 3) out.add(c1);
        if (n2 > nums.length / 3) out.add(c2);
        return out;
    }
}

Edge cases to test

  • No value crosses n / 3
  • Only one value crosses n / 3
  • Arrays of length 1 or 2

Hints

Hint 1

At most how many values can appear more than n / 3 times?

Hint 2

Extend Boyer–Moore voting to two candidates, then verify both with a second pass.

FAQ

What is the best time complexity for Majority Element II?

Optimal (Boyer–Moore with two candidates) runs in O(n) time and O(1) extra space. Two linear passes.

Which pattern does Majority Element II use?

It is a arrays & hashing problem that uses the moore's voting algorithm pattern. Other problems with the same pattern: Majority Element.

Is there a brute force solution for Majority Element II?

Yes. Brute force (hash map count) takes O(n) time and O(n) space. Count every value and keep the ones whose count is above n / 3.

Which edge cases should I test for Majority Element II?

No value crosses n / 3; Only one value crosses n / 3; Arrays of length 1 or 2.