Boyer–Moore Majority Voting: Why It Works, Why It Fails, and Where It Actually Belongs

Published: (January 4, 2026 at 02:28 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Introduction

The Boyer–Moore Majority Voting algorithm is often presented as a clever trick:

Find the majority element in O(1) space.

That statement is technically correct but practically misleading. This post documents the reasoning path I followed—from a defensible exact‑counting approach to a confidence‑based dominance signal, not an exact answer. The exploration began as a LeetCode problem and evolved into a system‑design question.

Majority Element Basics

Given a sequence of elements, a majority element appears more than ⌊n/2⌋ times.

  • Important constraints
    • There may or may not be a majority.
    • If a majority exists, it is unique.

Exact Counting (HashMap)

StepDescription
Traverse the dataMaintain a frequency map.
Count occurrencesKeep track of each candidate’s count.
Select candidateChoose the element with the highest count.
  • Time: O(n)
  • Space: O(k) where k is the number of distinct elements.

Exact counts allow arbitrary filtering (time ranges, tags, attributes) if counts are stored with appropriate structures (time buckets, filterable field buckets). No additional verification step is required, but memory grows with the cardinality of candidates—an unbounded requirement in streaming systems with large or unknown domains.

Boyer–Moore Majority Voting

Algorithm

  1. Maintain a candidate and a counter.
  2. For each element:
    • If counter is zero, set candidate to the current element.
    • If the current element equals candidate, increment counter.
    • Otherwise, decrement counter.
  3. After the first pass, verify the candidate in a second pass by counting its occurrences.
  • Time: O(n)
  • Space: O(1)

If a majority element exists, Boyer–Moore will return it as the final candidate. However, the algorithm does not guarantee:

  • That a majority exists.
  • That the returned candidate is a majority without verification.

Verification (Second Pass)

count = 0
for each element:
    if element == candidate:
        count += 1
if count > n/2:
    return candidate   // true majority
else:
    return None        // no majority

Without this verification step, the algorithm may return a false majority, and correctness is not guaranteed.

Why Not Just Use a HashMap?

If a second traversal and persistent data are required anyway, the obvious objection is:

Why not just use a HashMap?

This objection is valid. Before choosing an algorithm, it helps to describe the problem domain, not the tool.

Domains Where Boyer–Moore Shines

Consider systems that process:

  • Continuous streams of events.
  • High‑cardinality identifiers.
  • Potentially unbounded input.
  • Fixed memory budgets.

Typical examples:

  • Monitoring and alerting pipelines.
  • Event ingestion layers.
  • Abuse or anomaly detection systems.
  • Load‑shedding and back‑pressure mechanisms.

In these contexts, the goal is often not to compute exact counts but to answer questions like:

“Is something dominating the system right now?”

Assume we process events in fixed windows (e.g., hourly) containing millions of events with unbounded event types. Memory usage must remain stable.

HashMaps solve the problem perfectly until cardinality explodes. Boyer–Moore looks attractive because of constant space, but naïvely emitting the candidate each window leads to noisy, false‑positive alerts and alert fatigue.

Interpreting the Counter as a Confidence Signal

The key insight is that the counter is not a frequency; it is a dominance margin—how strongly the candidate resisted cancellation. This information is meaningful even without exact counts.

Signal Construction

PairMeaning
(candidate, counter)A signal, not a fact.
confidence = counter / window_sizeNormalized strength.
  • Random data → confidence near 0.
  • Dominant data → confidence grows.
  • Frequent candidate flips → low confidence.
  • Persistent candidate → higher confidence.
  • Oscillating counter → noise.
  • Increasing counter → emerging dominance.

Decisions are gated on persistence and growth, not on mere existence.

Suitable Applications

  • Streaming alerting systems.
  • Back‑pressure detection.
  • Anomaly or abuse signals.
  • Memory‑constrained ingestion paths.

Unsuitable Applications

  • Reporting.
  • Historical analysis.
  • Compliance or billing.

Relation to Misra–Gries

Boyer–Moore can be seen as a special case of the Misra–Gries algorithm with k = 2. Misra–Gries generalizes the idea:

  • Tracks multiple candidates.
  • Still bounds memory.
  • Trades precision for coverage.

Exploring Misra–Gries is a natural next step for deeper investigation.

Origin of the Exploration

The investigation started with a LeetCode problem:

Majority Element II

Solving the problem was easy; understanding where the algorithm makes sense was not.

Takeaway

  • Boyer–Moore is not an exact counting algorithm.
  • It is a bounded‑memory dominance signal.
  • Used as such, it is defensible.
  • Used as anything else, it is misleading.

That distinction is the entire point of this post.

Back to Blog

Related posts

Read more »