intermediate10 min read·Updated October 14, 2026

Majority Element (Boyer–Moore) Explained: Tracing [3, 2, 3]

Master the Boyer-Moore Voting Algorithm with a step-by-step trace of [3, 2, 3]. Understand the tug-of-war mental model, state transitions, and $O(1)$ space.

By Learnisim AI·Published October 14, 2026
LEARNING ARCSetup → Model in the example → Full trace → Twist → Edge cases → Apply
PREREQUISITES
  • basic array iteration
  • conditionals
Boyer-Moore Majority Vote Algorithm — O(1) Space Cancellation Finding element appearing > n/2 times in [2, 2, 1, 1, 1, 2, 2] Constraint Check: Hash Map O(N) Space ❌ Sorting O(N log N) Time ❌ Boyer-Moore: O(N) Time & O(1) Space ✔ Phase: Step-by-Step State Transitions on [ 2, 2, 1, 1, 1, 2, 2 ] Val: 2 Idx: 0 Cand: 2 Count: 1 New Cand Val: 2 Idx: 1 Cand: 2 Count: 2 Reinforce Val: 1 Idx: 2 Cand: 2 Count: 1 Cancel (-1) Val: 1 Idx: 3 Cand: 2 Count: 0 Count Zero Val: 1 Idx: 4 Cand: 1 Count: 1 Switch Cand Val: 2 Idx: 5 Cand: 1 Count: 0 Cancel (-1) Val: 2 Idx: 6 (End) Cand: 2 Count: 1 SURVIVOR! The Tug-of-War Cancellation Model • Majority element > n/2 guarantees it cannot be fully neutralized by all minority elements combined. • When count == 0, we reset the candidate to the current element, treating it as a fresh baseline. Example [3, 2, 3] → Cand: 3 wins instantly. Candidate & Count State Transitions 1. If count == 0: set candidate = nums[i] 2. If nums[i] == candidate: increment count (+1) 3. If nums[i] != candidate: decrement count (-1) Result: Final candidate is the guaranteed majority.
Majority in [3, 2, 3] and in [2, 2, 1, 1, 1, 2, 2] overview diagram
Why

Why Counting Frequencies the Naive Way Falls Short

Phase 1: The Space Penalty of Frequency Counting

Imagine you are handed an array of integers, such as [3, 2, 3], with a length . Your goal is to find the majority element—the value that appears strictly more than times. In our first case, that number is 3. Later, we will face a longer sequence: [2, 2, 1, 1, 1, 2, 2], where the majority element is 2. How would you normally solve this?
If you reach for a hash map to count every occurrence, you instantly violate our constraint of extra space. For a massive dataset, allocating a frequency table for every unique element consumes memory proportional to the number of distinct items. When scales into the millions, building a full frequency dictionary becomes a severe performance bottleneck.
What if we sort the array to find the middle element? Sorting solves the space problem in-place, but it forces a time complexity of . Can we do better? Can we identify the dominant value in a single linear pass without saving every distinct number in memory?
To see why this is tricky, look at how the numbers clash in [2, 2, 1, 1, 1, 2, 2]. The minority elements try to drown out the majority, yet the majority still holds a strict numerical advantage. We need a mechanism that lets elements cancel each other out dynamically, preserving only the survivor.
Why Counting Frequencies the Naive Way Falls Short (Boyer-Moore Setup) Analyzing space penalties and sorting bottlenecks before linear cancellation Target Sequences (Majority > n/2) Case A: [3, 2, 3] (n = 3, Majority = 3) 3 2 3 Case B: [2, 2, 1, 1, 1, 2, 2] (n = 7, Majority = 2) 2 2 1 1 1 2 2 Approach 1: Hash Map Frequency Counting Key : Frequency 3 : 2 occurrences 2 : 1 occurrence ... O(N) Space Penalty Memory Bottleneck • Allocates table for every distinct item value. • Fails when N scales into millions of items. Approach 2: In-Place Sorting Sorted Array: [1, 1, 1, 2, 2, 2, 2] • Solves space issue by modifying in-place. • Forces O(N log N) time complexity bottleneck. The Ideal Solution: Boyer-Moore Algorithm Dynamic Pair Cancellation in O(N) Time • Candidate & Count tracker replaces hash maps. • Majority survives minority clashes in a single pass!
Why Counting Frequencies the Naive Way Falls Short diagram
Model

The Tug-of-War Model: How Cancellation Finds the Survivor

Phase 2: The Tug-of-War Model

When scanning through our locked example nums = [3, 2, 3], we want to avoid building a heavy frequency map of every element. Instead, imagine a political election or a tug-of-war where every element with a different value cancels out an opposing vote. We maintain a single candidate and a count representing its current surplus of supporters. If the count drops to zero, the current candidate has been entirely depleted, and we simply adopt the next incoming element as our new candidate with a count of 1.
Let us trace the first two items of our primary array [3, 2, 3] through this mental model. We start with candidate = None and count = 0. When we see 3, the count is zero, so candidate = 3 and count = 1. Next, we inspect 2. Since 2 does not equal our candidate 3, we decrement count to 0. The candidate 3 and the challenger 2 have mutually canceled each other out.
This cancellation mechanic guarantees that if a true majority element exists—appearing strictly more than times—it possesses more votes than all other elements combined. Even if the non-majority elements gang up on it, the sheer density of the majority guarantees it will outlast the skirmish and hold the candidate seat at the end of the array.

Mathematical Guarantee

Let be the majority element in an array of length , appearing times where . The remaining elements sum to appearances. Because , the difference is strictly greater than zero. This positive net surplus ensures that no matter how the elements are interleaved, cannot be permanently defeated.
Boyer-Moore Majority Vote: The Tug-of-War Model Cancellation mechanics find the survivor in O(n) time & O(1) space Phase 1: Scanning Stream [3, 2, 3] 3 idx 0 2 idx 1 3 idx 2 Count drops to 0, then rebounds! Phase 2: Tug-of-War State CURRENT CANDIDATE Val: 3 SURPLUS VOTES (COUNT) Count: 1 Step-by-Step Cancellation Trace on [3, 2, 3]: Step 1: Inspect '3' Count is 0. Adopt new candidate. Candidate = 3 | Count = 1 Step 2: Inspect '2' (Challenger) Mismatch! 2 != 3. Mutual cancellation. Candidate = 3 | Count = 0 Step 3: Inspect '3' (Reinforcement) Count was 0, now reborn & reinforced. Candidate = 3 | Count = 1 The Mathematical Guarantee: Why Density Always Wins Majority element appears > n/2 times, ensuring it possesses more votes than all other elements combined. Even if all non-majority elements gang up in a skirmish, the true majority outlasts the cancellation and holds the seat. SURVIVOR FOUND Result: 3
The Tug-of-War Model: How Cancellation Finds the Survivor diagram
Worked example

Tracing the Boyer-Moore Algorithm Step by Step on Arrays

Phase 3: Walking Through the Candidate Duel

Let us run the tug-of-war model explicitly on our two working examples: nums = [3, 2, 3] and nums = [2, 2, 1, 1, 1, 2, 2]. We maintain two variables during the pass: candidate (initialized to None or an arbitrary value) and count (initialized to 0). Every time count hits 0, we adopt the current element as our new candidate. Then, if the current element matches the candidate, we increment count; otherwise, we decrement it.

Trace 1: nums = [3, 2, 3]

- Given: nums = [3, 2, 3] with . The majority element must appear strictly more than times (i.e., at least 2 times).
- Step 1: Start with candidate = None, count = 0.
- Step 2: Inspect x = 3. Since count == 0, set candidate = 3. Now x == candidate, so count becomes 1. State: candidate = 3, count = 1.
- Step 3: Inspect x = 2. Since 2 != 3, decrement count to 0. State: candidate = 3, count = 0.
- Step 4: Inspect x = 3. Since count == 0, reset candidate = 3. Now x == candidate, so increment count to 1. State: candidate = 3, count = 1.
- Result: Loop ends. The surviving candidate is 3, which correctly matches our expected result.

Trace 2: nums = [2, 2, 1, 1, 1, 2, 2]

- Given: nums = [2, 2, 1, 1, 1, 2, 2] with . The majority threshold is times (at least 4 times).
•Steps: Let us trace the intermediate states at each index:

- Index 0 (x = 2): count == 0, so candidate = 2, count = 1.
- Index 1 (x = 2): 2 == candidate, so count increments to 2. State: candidate = 2, count = 2.
- Index 2 (x = 1): 1 != candidate, so count decrements to 1. State: candidate = 2, count = 1.
- Index 3 (x = 1): 1 != candidate, so count decrements to 0. State: candidate = 2, count = 0.
- Index 4 (x = 1): count == 0, so candidate = 1, count = 1.
- Index 5 (x = 2): 2 != candidate, so count decrements to 0. State: candidate = 1, count = 0.
- Index 6 (x = 2): count == 0, so candidate = 2, count = 1.
- Result: The final surviving candidate is 2, which appears 4 times out of 7 and satisfies our condition.
Try this: Trace the execution of Boyer-Moore on nums = [1, 1, 2, 1, 2, 2, 2] with n=7. What is the candidate and count after processing the fourth element (value 1 at index 3)?
Boyer-Moore Trace: nums = [3, 2, 3] Active Variables: candidate = 3, count = 1 Step 1: Init cand = None count = 0 Step 2: x = 3 count == 0 cand = 3 count = 1 Step 3: x = 2 2 != 3 (mismatch) count -> 0 Step 4: x=3 cand = 3 count = 1 Result & Verification Surviving candidate is 3 (Count > 0)
Tracing the Boyer-Moore Algorithm Step by Step on Arrays diagram
Practice

Predicting the Candidate and Count State Transitions

Now that you have seen how cand and count evolve across [3, 2, 3] and [2, 2, 1, 1, 1, 2, 2], it is your turn to trace a small variant. Consider the array nums = [1, 1, 2, 1, 2]. With length , the majority threshold is strictly greater than occurrences. As you step through each element from left to right, track how the candidate resets when the count drops to zero.

Phase 4: Practice

To solidify the tug-of-war model, trace the loop iteration by iteration:
- Start with cand = None, count = 0.
- For x = 1, count becomes 1, cand = 1.
- For x = 1, count becomes 2, cand = 1.
- For x = 2, count drops to 1, cand remains 1.
- Continue for the remaining elements 1 and 2 to see who ultimately holds the field.
The Practice Challenge:
Write out or mentally determine the exact (cand, count) pair immediately after processing the fourth element (x = 1) in nums = [1, 1, 2, 1, 2], and state what the final returned candidate will be.
Try this: nums = [1, 1, 2, 1, 2]

Trace: initial (None, 0)

x = 1 -> (1, 1)

x = 1 -> (1, 2)

x = 2 -> (1, 1)

x = 1 -> ?

x = 2 -> ?

Apply

Applying Boyer-Moore to Beyond-Majority Streams and Related Problems

Phase 5: Applying Boyer-Moore Beyond the Basics

Now that you have traced the Boyer-Moore cancellation loop on nums = [3, 2, 3] and [2, 2, 1, 1, 1, 2, 2], it is time to transfer this pattern to a related variant. The core insight of Boyer-Moore is not just about finding a majority element; it is about maintaining a stabilizing candidate against a background of noise through pairwise reduction. Consider a modified problem: what if we need to find all elements that appear more than times in an array of size , still using extra space beyond our fixed output size?
To solve this generalized version, our single-candidate tug-of-war model naturally expands into a two-candidate duel. Instead of tracking one cand and count, we now maintain up to two candidates (cand1, cand2) and their respective counts (count1, count2). As you iterate through the stream, each incoming element is compared against both active candidates. If it matches one, its count increments. If neither matches and an empty slot is available, it becomes a new candidate with a count of 1. If both slots are occupied and it matches neither, both counts decrement by 1, effectively canceling out three distinct elements at once.
After passing through the entire array once to find potential survivors, a mandatory second verification pass is required to count the actual frequencies of cand1 and cand2. This mirrors the verification step we discussed for standard majority elements when the existence of a majority is not guaranteed. By adapting the cancellation invariant from one candidate to candidates, you can solve the threshold problem with optimal linear time and constant auxiliary space.
python
def majority_element_n_over_3(nums):
    # TODO: Implement the two-candidate Boyer-Moore variant
    pass

FAQ

How does Boyer-Moore find the majority element in [3, 2, 3]?
It maintains a candidate and a count. When iterating through [3, 2, 3], 3 starts as candidate with count 1. Seeing 2 decrements the count to 0, resetting the candidate. Finally, seeing 3 sets the candidate to 3 with count 1, returning 3 as the correct majority element.
What is the time and space complexity of the Boyer-Moore algorithm?
The Boyer-Moore algorithm runs in time by making a single pass (or two passes if verification is needed) through the array, and requires auxiliary space because it only tracks two variables: a candidate and a counter.
Does Boyer-Moore work if the array does not contain a guaranteed majority element?
The basic algorithm always outputs a candidate, but if a majority element is not guaranteed to exist in the input, a second verification pass is required to count occurrences of the candidate and confirm if its frequency exceeds .

Keep learning