Majority element - parts of an array
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The classic majority-element problem asks whether some value appears more than half the time in an array. The harder variant asks the same question for parts of an array, such as a subrange from index l to r. That change matters because the best algorithm for one whole-array answer is not automatically the best algorithm for many range queries.
Whole Array Versus Subarray Queries
For the whole array, the standard solution is Boyer-Moore voting. It finds a candidate in linear time with constant extra space, then verifies the candidate with a second pass.
That works beautifully for one global answer. It does not solve repeated range queries efficiently because you would have to rerun the logic on each subarray.
Why Subranges Need Preprocessing
Suppose the same array is queried thousands of times:
- majority in indices
0through10 - majority in indices
5through40 - majority in indices
100through200
Brute-force counting on every query is simple but can become too slow. For many queries, it is worth preprocessing the array.
A practical exact strategy is:
- build a structure that can return a candidate for a range
- verify that candidate's true frequency in that range
The second step is essential. Candidate retrieval alone can produce a value that is not actually a majority in that particular interval.
Segment Tree for Candidates
A segment tree can store majority-style candidates using Boyer-Moore merge logic. Each node holds a pair of values: a candidate and a relative count.
This gives fast range candidates and exact verification.
Why Verification Still Matters
The segment tree merge logic preserves a plausible candidate, not a proof. A range candidate must still be counted.
That is why the position lists are useful. For each distinct value, store the sorted indices where it appears. Then use binary search to count how many times it falls inside the query range.
This count step converts a plausible answer into a correct answer.
Complexity Tradeoffs
If you only need one answer for one array, use Boyer-Moore.
If you need many subrange majority queries:
- preprocessing costs more up front
- queries become much faster
- exact verification keeps correctness intact
This is the typical tradeoff in range-query problems. The right design depends on how many queries you expect.
When a Simpler Method Is Enough
If the array is small or there are only a few queries, a brute-force solution may be better because it is shorter and less error-prone.
That is not optimal for large workloads, but it is perfectly reasonable when performance requirements are modest.
Common Pitfalls
One common mistake is treating the candidate returned by a segment-tree merge as automatically correct. It still has to be verified.
Another mistake is using greater-than-or-equal-to half instead of strictly greater than half. Majority means more than half, not at least half.
Developers also often introduce off-by-one errors in the binary-search verification step, especially around inclusive right bounds.
Finally, not every problem needs heavy preprocessing. If query volume is small, brute force may be the better engineering choice.
Summary
- Boyer-Moore is excellent for finding a majority element in the whole array.
- Subrange majority queries are a different problem and usually need preprocessing.
- A segment tree can provide range candidates efficiently.
- Candidate answers still need exact frequency verification.
- Choose preprocessing only when the number of queries justifies the extra complexity.

