01 Introduction
The majority element problem shows up constantly in coding interviews — at Amazon, Google, Microsoft, and just about every other company that asks DSA questions. It looks easy on the surface. Most beginners grab a nested loop or a dictionary right away. But the real trick? There's an algorithm that solves it in a single pass with no extra memory at all.
That algorithm is called the Boyer-Moore Voting Algorithm, and once you understand how it works, it becomes one of those patterns you never forget. This guide walks you through every approach — from brute force to the optimal solution — step by step, with a dry run, Python code, and everything you'd need to confidently explain this in an interview.
02 Problem Statement
Given an array of integers nums of size n, find the element that appears more than n/2 times. This element is called the majority element. You may assume that the majority element always exists in the array.
Example 1
Input: nums = [3, 2, 3]
Output: 3
Why: Array size is 3. Element 3 appears 2 times. 2 > 3/2 = 1.5 ✓
Example 2
Input: nums = [2, 2, 1, 1, 1, 2, 2]
Output: 2
Why: Array size is 7. Element 2 appears 4 times. 4 > 7/2 = 3.5 ✓
03 Input / Output Format
- First line: integer
n— size of array - Second line:
nspace-separated integers
- A single integer — the majority element
- If none exists: print
-1(for extended version)
04 Constraints
1 ≤ n ≤ 5 × 10⁴-10⁹ ≤ nums[i] ≤ 10⁹- The majority element is guaranteed to exist in the array
05 Why This Problem Matters
🎯 Interview Pattern
This problem tests your knowledge of optimal space usage and teaches the "voting" pattern — which appears in majority vote, leader elections, and similar problems.
🏛 Real World Analogy
Think of an election where one candidate wins if they get more than half the votes. Boyer-Moore mimics that voting and cancellation logic perfectly.
🔁 Pattern Recognition
Once you master this, problems like "find element appearing more than n/3 times" become straightforward extensions of the same idea.
06 Naive Approach — Brute Force O(n²)
The simplest thing you can do: for each element, count how many times it appears in the array by scanning the whole array again. If the count exceeds n/2, return that element.
# Brute Force — O(n²) time, O(1) space def majority_brute(nums): n = len(nums) for i in range(n): count = 0 for j in range(n): if nums[j] == nums[i]: count += 1 if count > n // 2: return nums[i] return -1 # No majority element found
07 Better Approach — HashMap / Dictionary O(n)
Use a dictionary to count the frequency of each element in one pass. Then check which element has a count greater than n/2. This is much better than brute force but still uses O(n) extra space.
# HashMap Approach — O(n) time, O(n) space def majority_hashmap(nums): n = len(nums) freq = {} for num in nums: freq[num] = freq.get(num, 0) + 1 for num, count in freq.items(): if count > n // 2: return num return -1
collections.Counter does the same thing in one line: Counter(nums).most_common(1)[0][0]. But interviewers prefer you to implement it from scratch.
08 Optimal — Boyer-Moore Voting Algorithm
This is the clever one. The key insight is: if you pair up every occurrence of the majority element with a different element and cancel them out, you'll always have the majority element left over.
Here's how it works step by step:
- Start with
candidate = Noneandcount = 0 - For each element in the array:
- If
count == 0, set this element as the new candidate - If the element equals the candidate, increment count
- Otherwise, decrement count (they cancel each other)
- If
- At the end,
candidateholds the majority element
# Boyer-Moore Voting Algorithm — O(n) time, O(1) space def majority_boyer_moore(nums): candidate = None count = 0 for num in nums: if count == 0: candidate = num # New candidate selected if num == candidate: count += 1 # Same as candidate — support it else: count -= 1 # Different — cancel one vote return candidate
Just 8 lines. No extra space. Single loop. That's the beauty of it.
09 Visual Flowchart
10 Pseudocode
FUNCTION findMajorityElement(nums):
candidate ← NULL
count ← 0
FOR EACH num IN nums DO:
IF count == 0 THEN:
candidate ← num
END IF
IF num == candidate THEN:
count ← count + 1
ELSE:
count ← count - 1
END IF
END FOR
RETURN candidate
END FUNCTION
11 Full Python Program — All 3 Methods
# ───────────────────────────────────────────────────── # Find Majority Element — All 3 Approaches # Author : Siva Sankar | pro.technaga.com # Problem : Element appearing more than n/2 times # ───────────────────────────────────────────────────── # ── METHOD 1: Brute Force — O(n²) Time, O(1) Space ── def majority_brute(nums): n = len(nums) for i in range(n): count = 0 for j in range(n): if nums[j] == nums[i]: count += 1 if count > n // 2: return nums[i] return -1 # ── METHOD 2: HashMap — O(n) Time, O(n) Space ── def majority_hashmap(nums): n = len(nums) freq = {} for num in nums: freq[num] = freq.get(num, 0) + 1 for num, count in freq.items(): if count > n // 2: return num return -1 # ── METHOD 3: Boyer-Moore — O(n) Time, O(1) Space ── def majority_boyer_moore(nums): candidate = None count = 0 for num in nums: if count == 0: candidate = num count += 1 if num == candidate else -1 return candidate # ── MAIN — User Input ── if __name__ == "__main__": n = int(input("Enter array size: ")) nums = list(map(int, input("Enter elements: ").split())) print("\n── Results ──") print(f"Brute Force : {majority_brute(nums)}") print(f"HashMap : {majority_hashmap(nums)}") print(f"Boyer-Moore : {majority_boyer_moore(nums)}")
12 Dry Run — Step by Step
Let's trace through nums = [2, 2, 1, 1, 1, 2, 2] using Boyer-Moore.
| Step | Current Num | Count Before | Action | Candidate | Count After |
|---|---|---|---|---|---|
| 1 | 2 | 0 | count=0 → candidate=2, count+1 | 2 | 1 |
| 2 | 2 | 1 | num==candidate → count+1 | 2 | 2 |
| 3 | 1 | 2 | num≠candidate → count-1 | 2 | 1 |
| 4 | 1 | 1 | num≠candidate → count-1 | 2 | 0 |
| 5 | 1 | 0 | count=0 → candidate=1, count+1 | 1 | 1 |
| 6 | 2 | 1 | num≠candidate → count-1 | 1 | 0 |
| 7 | 2 | 0 | count=0 → candidate=2, count+1 | 2 | 1 |
candidate = 2. Element 2 appears 4 times in an array of size 7. 4 > 3.5, so it's the majority element. Correct! ✓
13 Time & Space Complexity
| Approach | Time Complexity | Space Complexity | Verdict |
|---|---|---|---|
| Brute Force | O(n²) | O(1) | Too slow for large inputs |
| HashMap | O(n) | O(n) | Fast but uses extra space |
| Boyer-Moore | O(n) | O(1) | ✅ Best — use this in interviews |
14 Test Cases
15 Edge Cases to Watch Out For
- Single element array: Always the majority. Count becomes 1 immediately.
- All same elements: Candidate never changes. Count keeps increasing.
- No majority exists: Boyer-Moore still returns a candidate — but it could be wrong. Always verify with a second pass if the majority is NOT guaranteed.
- Negative numbers: The algorithm handles them perfectly since it only checks equality, not magnitude.
- Even-length arrays: Majority needs to appear strictly more than n/2 times, not just n/2.
16 Common Interview Questions
Q1. What is the majority element?
An element that appears more than n/2 times in an array of size n. It's also called the dominant element or the absolute majority.
Q2. Can there be more than one majority element?
No. If one element appears more than n/2 times, there can't be another doing the same — they'd together exceed n elements, which is impossible.
Q3. Does Boyer-Moore work if no majority exists?
It returns a candidate, but that candidate might not be the majority. If the majority is not guaranteed, add a second pass to verify the count exceeds n/2.
Q4. What if we need elements appearing more than n/3 times?
You can extend Boyer-Moore to track two candidates and two counts simultaneously. This is LeetCode 229 — Majority Element II.
Q5. Is sorting the array a valid approach?
Yes — after sorting, the middle element nums[n//2] is always the majority. But this takes O(n log n) time, which is worse than Boyer-Moore's O(n).
17 Real World Applications
Find which candidate got the absolute majority of votes in an election — same exact logic.
Identify the dominant opinion in a survey response dataset without storing all responses in memory.
In real-time data streams, find the most frequent value without storing the entire stream — Boyer-Moore handles this in O(1) space.
18 Mistakes Beginners Make
- Forgetting to check count == 0 before updating: You must reset the candidate when count drops to zero, not after.
- Using >= instead of >: Majority means strictly more than n/2, not equal to n/2.
- Using integer division wrong:
n // 2is correct — don't forget the floor division. - Assuming Boyer-Moore always works without verification: If majority is not guaranteed, you need a second pass to confirm.
- Not handling empty arrays: Always add a guard check if the input might be empty.
19 Conclusion
The majority element problem is a classic that every developer preparing for coding interviews should have in their toolkit. The progression from brute force → hashmap → Boyer-Moore teaches a valuable lesson: sometimes, a clever observation (the majority can't be cancelled out) leads to a dramatically better solution.
Boyer-Moore Voting Algorithm is elegant because it does something most people wouldn't expect: it solves a frequency problem without counting frequencies. If you understand why it works — not just how — you'll be able to adapt it to related problems instantly.
20 FAQ
Counter(nums).most_common(1)[0][0] works, but it uses O(n) space. Interviewers often want you to implement the O(1) space solution using Boyer-Moore.