Majority Element
An element appears more than ⌊n/2⌋ times. Return it. (It is guaranteed to exist.)
Intuition
The majority element outnumbers everything else combined. If we pair off each majority vote against one non-majority vote, the majority always has leftovers. Boyer-Moore voting exploits exactly this cancellation.
Boyer-Moore voting. Pair off every occurrence of the majority element with a different element; because it appears more than n/2 times, it cannot be fully cancelled and whatever survives is the answer. One variable, one counter, no extra space — and the correctness argument is short enough to state in an interview, which is the point of the question.
Approach
The easy answer, and why we can do better
Counting occurrences in a hash map and returning the one above n/2 works and is O(n) time — but it uses O(n) extra space. The problem has special structure we can exploit: one element appears more than all the others combined. That strict majority is a strong promise, and it lets us solve it with two integers instead of a whole map.
Pair off opposites until one survivor remains
Imagine repeatedly removing two elements with different values — each removal deletes one majority element and one non-majority element at most. Because majority elements strictly outnumber everyone else, they can never be fully cancelled; some must survive. Boyer-Moore voting implements this with a candidate and a count: a matching value votes +1, a different value votes −1, and these −1s are exactly the 'cancellations.'
Re-elect whenever the count hits zero
Walk once. Whenever count drops to 0, the cancellations have wiped out the current candidate, so adopt the current element as the new candidate. Then apply its vote. Even if early noise installs a wrong candidate, a strict majority guarantees it gets re-elected and ends with count > 0. The final candidate is the answer — O(n) time, O(1) space.
Solution & live demo
Common pitfalls
Counting with a hash map
counts = Counter(nums) return max(counts, key=counts.get)
if count == 0: candidate = n count += 1 if n == candidate else -1
Correct, but O(n) space where the follow-up asks for O(1). Voting achieves the same in two scalars because the majority guarantee makes cancellation safe.
Replacing the candidate whenever a different value appears
if n != candidate:
candidate = n; count = 1if count == 0:
candidate = n
count += 1 if n == candidate else -1The candidate only changes once its lead is fully spent. Swapping on every mismatch discards a genuine majority element the moment any other value shows up.
Assuming a majority always exists
return candidate
return candidate # guaranteed by the constraints
Worth knowing the limit: the algorithm returns something even when no element exceeds n/2. This problem promises one exists — for the variant that doesn't, a second pass must verify the candidate's count.
Edge cases
Even if early non-majority votes set a wrong candidate, the trailing majority resets and re-elects itself — the count cannot survive against a strict majority.
count starts 0, the element becomes the candidate, and is returned.
That is still a strict majority, so cancellations leave the candidate standing.