Majority Element
You are given an integer list nums of length n. One value in it is a majority element: it occupies strictly more than half of the positions, that is, it appears more than ⌊n / 2⌋ times.
Return that value. The input is guaranteed to contain a majority element, so there is always exactly one correct answer.
A hash map makes this straightforward; the interesting challenge is to solve it in linear time while using only a constant amount of extra memory.
Example 1
Example 2
Example 3
Constraints
1 <= n <= 5 * 104-109 <= nums[i] <= 109- A majority element always exists.
Pattern Path · Hashing & Counting · problem 5 of 169
Start simple
For each element, count how many times it appears with a second loop and return the first one above n/2: O(n²) time, O(1) space.
The key idea
The Boyer-Moore voting idea: think of every occurrence of the majority as a vote for it and every other element as a vote against it. Because the majority holds more than half of the positions, it has more votes than all other values combined, so it survives any sequence of one-for-one cancellations.
We simulate those cancellations with a candidate and a count. When count is 0, the current element becomes the candidate. An element equal to the candidate adds 1; a different element cancels one vote by subtracting 1.
Every time count drops back to 0, the prefix we just processed can be split into pairs of different values, so at most half of it was the majority. That means the majority still holds more than half of the remaining suffix, and the argument repeats. The candidate left at the end must therefore be the majority.
If the majority were not guaranteed, a second pass to verify the candidate's count would be needed.
Complexity
- Time:
O(n) - Space:
O(1)
Python
class Solution:
def majorityElement(self, nums: List[int]) -> int:
candidate, count = None, 0
for x in nums:
if count == 0:
candidate = x # start a new voting round
count += 1 if x == candidate else -1
return candidate
JavaScript
var majorityElement = function(nums) {
let candidate = null;
let count = 0;
for (const x of nums) {
if (count === 0) candidate = x; // start a new voting round
count += x === candidate ? 1 : -1;
}
return candidate;
};
What the interviewer is checking
The hash-map solution is expected; the interviewer is really checking whether you can find (and justify) the constant-space voting algorithm.
Mistakes to avoid
- Resetting the candidate on any mismatch instead of only when the count reaches zero.
- Assuming the candidate is valid when the problem does not guarantee a majority (verify with a second pass).
- Sorting and returning the first element instead of the middle one.
Follow-ups to expect
- What if no majority is guaranteed? (Second pass to verify the count.)
- Find every value appearing more than n/3 times. (Two candidates, two counters.)
- Can sorting help? (The middle element after sorting, O(n log n).)
In real software
Streaming "heavy hitter" detection, such as spotting the dominant source of traffic in a network or the leading value in a sensor feed, uses the same constant-memory voting idea.