AlgoMaster Logo

Majority Element II

Last Updated: March 31, 2026

medium

Understanding the Problem

This is a generalization of the classic Majority Element problem (LeetCode 169), where we needed to find the element appearing more than n/2 times. That problem guaranteed exactly one answer. Here, we need to find all elements appearing more than n/3 times.

The first thing to notice is a mathematical constraint: there can be at most two elements that appear more than n/3 times. Think about it. If three elements each appeared more than n/3 times, that would account for more than n total elements, which is impossible. So our answer list has at most 2 elements.

This observation is the foundation for every approach. The brute force counts every element, the hash map approach does it efficiently, and the optimal Boyer-Moore approach exploits this "at most 2 candidates" fact to use constant space.

Key Constraints:

  • 1 <= nums.length <= 5 * 10^4 → With n up to 50,000, O(n^2) means 2.5 billion operations, which is too slow. We need O(n log n) or better.
  • -10^9 <= nums[i] <= 10^9 → Values span the full 32-bit integer range, so we can't use array indexing for counting. We need a hash map or a comparison-based approach.
  • The follow-up explicitly asks for O(n) time and O(1) space, hinting at the Boyer-Moore Voting algorithm.

Approach 1: Hash Map Counting

Intuition

The most natural approach: count how many times each element appears, then check which counts exceed n/3. A hash map gives us O(1) lookups and insertions, so we can count everything in a single pass and then filter.

This is the approach most people would reach for in a real codebase. It's clean, readable, and hard to get wrong.

Algorithm

  1. Create a hash map to store the count of each element.
  2. Iterate through nums, incrementing the count for each element.
  3. Calculate the threshold as n / 3.
  4. Iterate through the hash map entries, collecting elements whose count exceeds the threshold.
  5. Return the result list.

Example Walkthrough

1Initialize: scan nums to count each element
0
3
i
1
2
2
3
1/6

Code

This approach works correctly but uses O(n) extra space. Since at most 2 elements can be the answer, can we find those candidates without storing counts for every element?

Approach 2: Sorting

Intuition

If we sort the array, all occurrences of the same element will be adjacent. An element that appears more than n/3 times will occupy a contiguous block of length greater than n/3. So after sorting, we can scan the array and check whether each element's run length exceeds the threshold.

This approach trades the O(n) space of a hash map for the O(n log n) time of sorting. It's a reasonable middle ground if you want constant auxiliary space and can afford the slower runtime.

Algorithm

  1. Sort the array.
  2. Initialize a counter and iterate through the sorted array.
  3. For each new value, count its consecutive occurrences.
  4. If the count exceeds n/3, add it to the result.
  5. Return the result.

Example Walkthrough

1Before sorting: nums = [3, 2, 3, 1, 2, 3, 2]
0
3
1
2
2
3
3
1
4
2
5
3
6
2
1/6

Code

Sorting works but takes O(n log n) and modifies the input. Since at most 2 elements can be the answer, can we find those candidates in a single pass without sorting or extra space?

Approach 3: Boyer-Moore Voting (Optimal)

Intuition

This is the extended version of the Boyer-Moore Majority Vote algorithm. The original algorithm finds the element appearing more than n/2 times using one candidate and one counter. For n/3, we extend it to two candidates and two counters.

The core idea is a cancellation mechanism. If three people all vote for different candidates, their votes cancel out. After all cancellations, whoever remains standing must be a potential majority candidate. But "potential" is the key word. We still need a second pass to verify.

Algorithm

  1. Initialize two candidates (cand1, cand2) and their counts (count1 = 0, count2 = 0).
  2. First pass (find candidates): iterate through nums:
    • If num == cand1, increment count1.
    • Else if num == cand2, increment count2.
    • Else if count1 == 0, set cand1 = num and count1 = 1.
    • Else if count2 == 0, set cand2 = num and count2 = 1.
    • Else decrement both count1 and count2.
  3. Second pass (verify candidates): count the actual occurrences of cand1 and cand2.
  4. Add to result any candidate whose count exceeds n/3.

Example Walkthrough

1Initialize: cand1=?, count1=0, cand2=?, count2=0
0
1
i
1
2
2
3
3
1
4
1
5
2
6
2
1/7

Code