14Moore's votingArrays and hashing
Moore's voting
Find the value that appears more than half the time, with one candidate and one count.
Clue: find the value that appears more than half the time, with O(1) extra space. Worked example: LeetCode 169, Majority Element (Easy). The pattern is Moore's voting (the Boyer–Moore majority vote algorithm).
The idea
Five friends vote on a drink. Two different votes? Both sit down: they cancel each other out. Same vote? They stand together, and the group grows by one. If over half chose tea, tea is left standing, because each cancel takes away at most one tea.
In code, keep one candidate and one count, the votes left. Same value: count up. Different value: count down. When count is 0, the next value becomes the candidate.
The walk
nums = [2, 1, 1, 3, 1] (2 is coffee, 1 is tea, 3 is juice). Answer: 1.
| x | candidate | count |
|---|---|---|
| 2 | 2 (new) | 1 |
| 1 | 2 | 0 (cancel) |
| 1 | 1 (new) | 1 |
| 3 | 1 | 0 (cancel) |
| 1 | 1 (new) | 1 |
Each pair takes away at most one 1. There are more 1s than all the rest, so a 1 is left. Quick check from the post: [5, 4, 4] gives candidate 4: 5 and the first 4 cancel, count is 0, so the last 4 becomes the candidate.
Pseudocode
function majorityElement(nums):
candidate = none
count = 0
for each x in nums:
if count == 0:
candidate = x // new candidate
if x == candidate:
count = count + 1
else:
count = count - 1
return candidateThe trap: no majority? You still get a candidate. [1, 2, 3] returns 3, but 3 appears once, which is not over half. When a majority is not promised, count the candidate once more and return it only if it appears more than floor(length(nums) / 2) times; otherwise there is none. LeetCode 169 promises a majority, so it skips this check. Each file below has both versions: majorityElement (LeetCode 169) and majorityOrNone (with the check).
Code
public class Main {
// LeetCode 169: a majority is guaranteed to exist.
static int majorityElement(int[] nums) {
int candidate = 0;
int count = 0;
for (int x : nums) {
if (count == 0) {
candidate = x;
}
if (x == candidate) {
count = count + 1;
} else {
count = count - 1;
}
}
return candidate;
}
// No guarantee: count the candidate again. Returns null when there is no majority.
static Integer majorityOrNone(int[] nums) {
if (nums.length == 0) return null;
int candidate = majorityElement(nums);
int seen = 0;
for (int x : nums) {
if (x == candidate) seen = seen + 1;
}
return seen > nums.length / 2 ? candidate : null;
}
}def majority_element(nums):
# LeetCode 169: a majority is guaranteed to exist.
candidate = None
count = 0
for x in nums:
if count == 0:
candidate = x
if x == candidate:
count = count + 1
else:
count = count - 1
return candidate
def majority_or_none(nums):
# No guarantee: count the candidate again.
if not nums:
return None
candidate = majority_element(nums)
seen = sum(1 for x in nums if x == candidate)
return candidate if seen > len(nums) // 2 else None#include <bits/stdc++.h>
using namespace std;
// LeetCode 169: a majority is guaranteed to exist.
int majorityElement(const vector<int>& nums) {
int candidate = 0;
int count = 0;
for (int x : nums) {
if (count == 0) {
candidate = x;
}
if (x == candidate) {
count = count + 1;
} else {
count = count - 1;
}
}
return candidate;
}
// No guarantee: count the candidate again.
optional<int> majorityOrNone(const vector<int>& nums) {
if (nums.empty()) return nullopt;
int candidate = majorityElement(nums);
long long seen = 0;
for (int x : nums) if (x == candidate) seen = seen + 1;
if (seen > (long long)nums.size() / 2) return candidate;
return nullopt;
}// LeetCode 169: a majority is guaranteed to exist.
function majorityElement(nums) {
let candidate = null;
let count = 0;
for (const x of nums) {
if (count === 0) {
candidate = x;
}
if (x === candidate) {
count = count + 1;
} else {
count = count - 1;
}
}
return candidate;
}
// No guarantee: count the candidate again.
function majorityOrNone(nums) {
if (nums.length === 0) return null;
const candidate = majorityElement(nums);
let seen = 0;
for (const x of nums) if (x === candidate) seen = seen + 1;
return seen > Math.floor(nums.length / 2) ? candidate : null;
}Complexity
- Time: O(n). One pass for LeetCode 169; two passes with the check.
- Extra space: O(1), just
candidateandcount. (A hash map of counts also takes O(n) time but O(n) space; sorting takes O(n log n).)
How it was tested
All four versions were compiled and run on the same 3,015 inputs (3,000 random arrays of length 0 to 12, half of them forced to have a majority, plus edge cases: empty, single element, all equal, no majority, sorted, reversed, values at ±10^9, and a 100,001-element array) and compared with a brute-force counter. Zero mismatches. Re-run on 31 October 2026 on 3,004 more inputs (3,000 random arrays of length 0 to 12, about half with a majority, plus the example, the quick check, the trap input and the empty array): all four matched on every one.
Practice
Try these in order. Open the worked example first if you got stuck on the slides.
- LeetCode 169 Majority Elementworked example
Over n/3 times now: keep two candidates.





