LeetCode #169 Medium

Majority Element

Majority Element is LeetCode 169 (Easy). Given an integer array nums of length n, return the majority element: the value that appears more than ⌊n / 2⌋ times. The input always contains one.

The follow-up asks for O(n) time and O(1) extra space, which rules out both a hash map of counts and sorting.

Constraints
  • n == nums.length
  • 1 <= n <= 5 * 10⁴
  • -10⁹ <= nums[i] <= 10⁹
  • The input is generated such that a majority element will exist in the array.
arrayboyer-moorecounting
Open on LeetCode ↗
02

Intuition

Pair up elements that are different and throw each pair away. Every pair removes at most one copy of the majority value. The majority has more copies than every other value combined, so it can never run out: after all the throwing away, it is what is left.

The Boyer-Moore voting algorithm performs that pairing in one pass without storing any pairs. It keeps a current candidate and a count of its copies not yet cancelled. Each different value cancels one copy, each matching value adds one, and because a majority is guaranteed to exist, the survivor is the answer.

How to spot this pattern

"More than half" is the signal. A value with over n/2 copies survives any cancellation of unequal pairs, so a single counter is enough. For "more than n/3" (Majority Element II) the same idea works with two candidates and two counters.

03

Approach

Try it first

Before reading on, solve it with a hash map. Then ask: can you do it without storing counts for every value? What happens if you cancel one majority element against one other element?

1

Start with no candidate

Set candidate = None and count = 0. The count is the number of candidate copies not yet cancelled by a different value, and starting at 0 means the very first element is adopted as the candidate.

2

Pick a candidate when the count is 0

Whenever count is 0, make the current element the new candidate. A count of 0 means everything seen so far has paired off evenly, so that prefix holds no majority and can be forgotten; the true majority must still win in the rest of the array.

3

Vote

Then compare the element with the candidate:

  • same value: count += 1, one more uncancelled copy;
  • different value: count -= 1, because this element and one candidate copy cancel as a pair.

Check for 0 before voting, or the new element cancels against nothing.

4

Return the candidate

Return candidate after the pass. With a guaranteed majority the survivor is correct. If the input might have no majority, a second pass must count the candidate and check count > n // 2, because the vote always leaves someone standing.

04

Majority Element solution in Python | C++ | Java

▶1class Solution:
▶2 def majorityElement(self, nums: List[int]) -> int:
▶3 candidate, count = None, 0
▶4 for x in nums:
▶5 if count == 0:
▶6 candidate = x
▶7 count += 1 if x == candidate else -1
▶8 return candidate
20211213142526candidatenonecount0no candidate yet
candidatenone
count0unmatched votes for the candidate
Boyer-Moore voting. Imagine every element is a vote. Whenever two different values meet, they cancel each other out. The majority value has more than half the votes, so it can never be cancelled completely: it is the only value that can be left standing.
20211213142526candidate2countcount 0 → 2 is candidate
nums[0]2same as candidate
candidate2new, because count was 0
count1+1
First element. Start fresh: 2 becomes the candidate with one vote.
20211213142526candidate2count2 agrees → +1
nums[1]2same as candidate
candidate2unchanged
count2+1
2 matches the candidate, so it adds a vote: count 2.
20211213142526cancelled paircandidate2count1 cancels 2 at 1
nums[2]1different from candidate
candidate2unchanged
count1-1
1 differs from the candidate 2, so it cancels one surviving 2 vote (index 1). The pair is set aside, and the count drops to 1.
20211213142526cancelled paircandidate2count01 cancels 2 at 0
nums[3]1different from candidate
candidate2unchanged
count0-1
1 differs from the candidate 2, so it cancels one surviving 2 vote (index 0). The pair is set aside, and the count drops to 0. The next element will start a new candidate.
20211213142526cancelled paircandidate1countcount 0 → 1 is candidate
nums[4]1same as candidate
candidate1new, because count was 0
count1+1
The count is 0, so every earlier element has been paired off. Start fresh: 1 becomes the candidate with one vote.
20211213142526cancelled paircandidate1count02 cancels 1 at 4
nums[5]2different from candidate
candidate1unchanged
count0-1
2 differs from the candidate 1, so it cancels one surviving 1 vote (index 4). The pair is set aside, and the count drops to 0. The next element will start a new candidate.
20211213142526cancelled paircandidate2countcount 0 → 2 is candidate
nums[6]2same as candidate
candidate2new, because count was 0
count1+1
The count is 0, so every earlier element has been paired off. Start fresh: 2 becomes the candidate with one vote.
20211213142526cancelled paircandidate2countreturn 2
answer2the value left standing
pairs cancelled3each removed at most one 2
Answer 2. Each cancelled pair used up at most one copy of the majority value, and the majority has more copies than all other values combined. So after all the pairing, it is the one left over. One pass, O(1) extra memory.
05

Hash map counting

Walk the array once, adding 1 to each value's count, and return a value as soon as its count goes above half the length.

▶1class Solution:
▶2 def majorityElement(self, nums: List[int]) -> int:
▶3 counts = {}
▶4 for x in nums:
▶5 counts[x] = counts.get(x, 0) + 1
▶6 if counts[x] > len(nums) // 2:
▶7 return x
06

Common pitfalls

Checking count == 0 after the vote

✗ Wrong
for x in nums:
    count += 1 if x == candidate else -1
    if count == 0:
        candidate = x
✓ Right
for x in nums:
    if count == 0:
        candidate = x
    count += 1 if x == candidate else -1

The new candidate must get its own vote. Switching after the vote leaves the count at 0 for the new candidate, so the next different element drives it negative and the logic breaks.

Reading the final count as the frequency

✗ Wrong
return candidate if count > len(nums) // 2 else -1
✓ Right
return candidate

count is the number of uncancelled votes, not how often the candidate appears. For [2, 2, 1, 1, 1, 2, 2] it ends at 1 although 2 appears 4 times. To verify a candidate, count it in a second pass.

Trusting the candidate when no majority is guaranteed

✗ Wrong
# input may have no majority
return candidate
✓ Right
if nums.count(candidate) > len(nums) // 2:
    return candidate
return -1

The algorithm always ends with some candidate. For [1, 2, 3] it returns 3, which is not a majority. LeetCode 169 guarantees one exists; many interview variants do not.

07

Edge cases

Majority not at the start

For [6, 5, 5] the first 5 cancels the 6 and the count drops to 0, so the second 5 becomes the candidate. The first element gets no special treatment.

08

Complexity

Time
O(n)
Space
O(1)
One pass and two variables. A hash map count is also O(n) time but O(n) space; sorting and taking nums[n // 2] is O(n log n).
09

Four ways to find the majority element

MethodIdeaTimeSpace
Boyer-Moore votingcancel unequal pairs; the majority survivesO(n)O(1)
Hash mapcount every value, return the one above n/2O(n)O(n)
Sortingthe majority must occupy index n // 2O(n log n)O(1) to O(n)
Majority Element II (229)two candidates for "more than n/3"O(n)O(1)
10

Majority Element FAQ

What is the majority element?

The value that appears more than ⌊n/2⌋ times in an array of length n. There can be at most one such value. In [2, 2, 1, 1, 1, 2, 2] it is 2 (4 of 7).

How does the Boyer-Moore voting algorithm work?
  • Idea: pair each majority vote against a different value; the majority has more than half, so it survives.
  • Variables: candidate and count, starting at none and 0.
  • Loop: if count == 0, set candidate = x; then count += 1 if x == candidate, else count -= 1.
  • Result: return candidate (verify with a second pass if a majority is not guaranteed).
  • Complexity: O(n) time, O(1) space.
  • Example: [2, 2, 1, 1, 1, 2, 2] gives 2.
Why does Boyer-Moore voting work?

Each decrement cancels one candidate vote against one different value. At most one copy of the true majority is lost per cancelled pair, and the majority has more copies than all other values together, so some copy is always left at the end, and that value must be the final candidate.

Why does sorting give the majority element?

A value filling more than half of the array must cover the middle position after sorting, whether it is the smallest or the largest value. So sorted(nums)[n // 2] is the majority.

How is Majority Element II different?

Majority Element II (229) asks for every value appearing more than ⌊n/3⌋ times. At most two such values exist, so the voting keeps two candidates and two counts, and a second pass verifies them.