Hi👋SpeedAlgo • Deliberate Practice & Cognitive Ergonomics for Software Engineers

An interactive algorithm mastery and technical interview preparation platform published by Hi👋WebEnterprise. Built for senior and staff software engineers preparing for rigorous coding screens at top tech companies (FAANG/MAMAA).

13 Core Algorithmic Patterns & 225 Practice Problems

  • 1. Two Pointers (16 Paradigms, 43 Problems): Opposite ends, sorted pair sums, palindrome verification, trapping rain water, 3Sum, container with most water — includes the Sliding Window and Fast & Slow Pointers paradigms (contiguous subarray invariants, longest substrings, Floyd's cycle detection, linked list middle).
  • 2. Binary Search (9 Paradigms, 14 Problems): Monotonic predicate partitioning (feasible(x)), boundary search, rotated sorted arrays, square roots, minimum ship capacity, median of two sorted arrays, matrix median on value range.
  • 3. Bit Manipulation (5 Paradigms, 11 Problems): Counting set bits, XOR cancellation, bit reversal, bitmask pairing, maximum XOR with a bitwise trie.
  • 4. Math & Geometry (8 Paradigms, 14 Problems): Sieve of Eratosthenes, integer/roman conversions, modular arithmetic, geometric simulation.
  • 5. Tree/Graph Depth-First Search (15 Paradigms, 24 Problems): Path sums, lowest common ancestor, tree diameter, validating BSTs, tree DP (House Robber III, Binary Tree Cameras).
  • 6. Tree/Graph Breadth-First Search (5 Paradigms, 12 Problems): Level-order traversals, shortest path in unweighted graphs, zig-zag traversals, rotting oranges, word ladders.
  • 7. Graphs (12 Paradigms, 22 Problems): Topological sort, cycle detection, Dijkstra's algorithm, bipartite graph validation, network delay.
  • 8. Backtracking (6 Paradigms, 14 Problems): Subsets, permutations, combinations, constraint satisfaction, pruning, N-Queens, Sudoku solver.
  • 9. Dynamic Programming (13 Paradigms, 28 Problems): Memoization vs tabulation, 0/1 knapsack, unbounded knapsack, coin change, edit distance, longest common subsequence.
  • 10. Heap / Priority Queue (9 Paradigms, 11 Problems): Running medians, top-k elements, interval scheduling, IPO, k-way merges.
  • 11. Advanced Data Structures (7 Paradigms, 17 Problems): Trie (prefix tree), Union-Find (Disjoint Set Union), LRU Cache, LFU Cache, range-sum queries with updates.
  • 12. Stack (5 Paradigms, 9 Problems): Next greater element, largest rectangle in histogram, remove k digits, decode string, min stack.
  • 13. Intervals & Greedy (2 Paradigms, 6 Problems): Merge intervals, interval scheduling, meeting rooms by sweep line, jump game.

4-Stage Deliberate Practice Framework

  1. Stage 1 (Compare & Learn): Read the pattern's mental model, loop invariant and Big-O proof, compare the pattern's template with the problem's solution side by side, and use the step-by-step debugger. The solution can also be shown in C#, Java, TypeScript, C++, Go or Rust for almost every problem.
  2. Stage 2 (Active Recall): Rebuild the solution from memory in a code editor, with an invariant checklist and optional progressive hints, and check it against a judged test suite.
  3. Stage 3 (AI Interview Coach, coming soon): A mock-interview stage still in development; for now, students go straight from Stage 2 to Stage 4.
  4. Stage 4 (Solve on Your Own): Solve a new problem on your own against a 15-minute timer; your code is graded against a test suite. Python and TypeScript run in your browser and C# runs on our server (design problems grade in Python and TypeScript).

Equipped with a spaced-repetition review hub on a fixed 7-step schedule (1 day up to 90 days), a two-pane Studio workspace, and study notes.

Pricing, Access & Commercial Terms

  • Core Curriculum: 100% Free. No credit card required.
  • Coins: New accounts get 40 free coins once, the daily claim adds +20 coins once a day, and inviting a friend earns you +25 coins when they complete their first practice step. These are the only ways to earn coins.
  • AI Coach: Each AI coach question costs 1-5 coins, priced by the server according to its size.
  • BYOK (Bring Your Own Key): AI coaching is free with your own Google Gemini, OpenAI or OpenRouter API key (BYOK).
  • Extras: Coins also unlock extras for 24 hours: a Recall hint level (1 coin), a Solve solution reveal (2), a LeetCode problem card's solutions (1) and a pattern's extra canonical problems (1).
  • Payments & Refunds: Nothing on the site is sold for money: coins can only be earned, never bought. There are no subscriptions or charges, so there is nothing to refund.
  • Platform Operator: Hi👋WebEnterprise. Support & policies at hispeedalgo.com.
Skip to main content
Hi👋SpeedAlgo

Invariant-First Algorithmic Mastery

Arena
238Items
Theory Context•Two Pointers & Sliding Window
EasyLC 169

Majority Element (LeetCode 169)

Target Frequency:AmazonGoogleMicrosoft

In an integer array nums of length n, one value takes up more than half of the positions: it occurs more than ⌊n / 2⌋ times, and every input is built so that such a value exists. That value is called the majority element. Return it.

Follow-up: can you find it in linear time with only O(1) extra space?

Worked Examples

Example 1
Input:nums = [3,2,3]
Output:3
30213233: 2 of 3
Explanation: n = 3, so the majority needs more than 1 copy. 3 occurs twice.
Example 2
Input:nums = [2,2,1,1,1,2,2]
Output:2
202112131425261 leads here2 wins: 4 of 7
Explanation: n = 7, so the majority needs more than 3 copies. 2 occurs four times and 1 three times.

⚖️Formal Constraints & Bounds

  • n == nums.length

  • 1 <= n <= 5 * 104

  • -109 <= nums[i] <= 109

  • The input is generated such that a majority element will exist in the array.

Deep-Dive & Conceptual Insights

Core Insight

Cancel each value against a different one: a value that fills more than half the array has more copies than all the others together, so some of its copies are still standing when the values run out.

Real-World Scenario & Production Applications

A cluster of replicas votes on a value, and more than half of them are known to agree; a stream of events is known to be dominated by one source. Counting every value needs memory that grows with the number of distinct values. Pairing off disagreeing values needs two variables, whatever the input size, and still finds the value that holds more than half.

Step-by-Step Execution Trace Table

Example 2, nums = [2,2,1,1,1,2,2] (the debugger's first preset; the trap is the step where 1 becomes the candidate):

xcount == 0 before x?candidatecount afterWhat happened
2yes212 starts a run
2no22a second copy of 2
1no211 cancels one 2
1no201 cancels the other 2: the first four values are paired off
1yes111 becomes the candidate, but 1 is not the majority: a candidate is only a survivor so far
2no102 cancels the 1
2yes212 starts the last run
endreturn candidate gives 2
Worked on Paper

The Math, Step by Step

1. The counts the code relies on

Let nnn be the length of nums, and let mmm be the majority value. The problem guarantees that mmm occurs more than ⌊n/2⌋\lfloor n / 2 \rfloor⌊n/2⌋ times. So mmm occurs more often than all other values together:

copies of m  >  copies of all other values\text{copies of } m \;>\; \text{copies of all other values}copies of m>copies of all other values

The code keeps two variables. candidate is a value, and count is the number of copies of candidate that are not yet cancelled.

2. One step: an element either adds a copy or cancels one

For each element x, one of three things happens:

CaseWhat the code doesMeaning
count == 0candidate = x, then count becomes 1nothing is left over, so x starts a new candidate
x == candidatecount += 1one more uncancelled copy of the candidate
x != candidatecount -= 1x and one copy of the candidate cancel each other

Each cancellation removes a pair of two different values: x and one earlier copy of the candidate. After any prefix of nums, the elements seen so far split into cancelled pairs of different values, plus count copies of candidate that are left over.

3. Why the majority is the candidate at the end

Every cancelled pair holds two different values, so it holds at most one copy of mmm. So each copy of mmm inside a pair uses up one element that is not mmm. The elements that are not mmm number fewer than the copies of mmm. So the pairs cannot use up every copy of mmm. At least one copy of mmm is left over at the end.

The left-over elements are all copies of candidate. At least one of them is mmm, so candidate is mmm, and count is at least 1. This argument is the Boyer-Moore voting algorithm.

The argument needs the guarantee of part 1. Without a majority, the final candidate can be any value. For example, [1, 2, 3] ends with candidate 3, which is not a majority. The problem promises a majority, so the code does not check it.

4. When count is 0

count == 0 means every element seen so far is inside a cancelled pair. The next element starts a new candidate. The order inside the loop matters. The code first sets candidate = x and then runs count += 1 if x == candidate else -1. Because x now equals candidate, count becomes 1. So count never drops below 0.

A candidate can change many times, as in Example 2. The only thing that matters is the candidate after the last element.

5. Example 2 by hand

nums = [2,2,1,1,1,2,2], so n=7n = 7n=7. The value 2 occurs 4 times, more than ⌊7/2⌋=3\lfloor 7 / 2 \rfloor = 3⌊7/2⌋=3.

xcount == 0 before?candidatecount afterWhat happened
2yes21new candidate 2
2no22one more 2
1no21this 1 cancels one 2
1no20this 1 cancels the other 2
1yes11new candidate 1
2no10this 2 cancels the 1
2yes21new candidate 2

The cancelled pairs are (2, 1), (2, 1) and (1, 2). Each holds one 2 and one 1. The left-over element is the last 2. The code returns 2, the expected output.

6. Example 1 by hand

nums = [3,2,3]. The first 3 becomes the candidate with count = 1. The 2 cancels it, so count is 0. The last 3 starts a new candidate with count = 1. The code returns 3, the expected output.

7. From the math to the code
MathIn majorityElement
nothing seen, nothing left overcandidate, count = None, 0
everything so far is cancelledif count == 0: followed by candidate = x
one more left-over copycount += 1 when x == candidate
a pair of different values cancelscount -= 1 when x != candidate
the left-over value is the majorityreturn candidate

The loop reads each element once, so the code takes O(n)O(n)O(n) time. It keeps two variables, so it uses O(1)O(1)O(1) extra space.

Code Shape
Archetype Code Shape
Python
1A value that fills more than half of `nums` has more copies than all the other values together: if each value cancels one copy of a different value, the majority still has copies left.
2Keep this true: before each `x`, the values read so far, except `count` copies of `candidate`, split into pairs of different values. When `count == 0`, everything so far is paired off.
3The shape: one loop over `nums` with two steps per value: first decide whether a new run starts, then update `count`. After the loop, return the value that is left standing.
4The trap: the survivor is only a candidate. Here it is safe to return because a majority is promised; in the middle of `[2,2,1,1,1,2,2]` the candidate is `1`, and without the promise you must count it again.

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

Counting every value works, but it needs memory for every distinct value. Boyer-Moore Voting needs two variables. Picture each value cancelling one copy of a different value: two different values leave together. The majority fills more than half of nums, so even if every other value cancels one of its copies, some copies are left. The code keeps only what hasn't been cancelled yet: candidate and count, the number of its copies still unpaired. A matching x adds a copy, a different x cancels one, and when count reaches 0 the next x becomes the new candidate.

🗳️ The Analogy: A Shouting Match in a Room

People from several parties walk into a room one at a time. Whenever someone meets a supporter of a different party already standing there, the two of them leave together. Supporters of the same party stay and wait. If one party brought more than half of all the people, the others can't pair off all of them: when the door closes, the people still standing belong to that party. You only ever need to remember which party is standing and how many of its people are there.

🔑 Why It Works

Before each x, the values already read, except count copies of candidate, can be split into pairs of different values. Each pair holds at most one copy of the majority, and there are fewer other values than copies of the majority, so the pairs can't use up all of its copies: it must be the value left standing at the end. The trap: that is a promise about the end only, and only because a majority exists. In the middle of [2,2,1,1,1,2,2] the candidate is 1, and on [1, 2, 3] the survivor is 3, which occurs once; when a majority is not promised, count the survivor again.

  • Trusting the survivor without a promise (the trap): return candidate is right here only because a majority exists. In the middle of [2,2,1,1,1,2,2] the candidate is 1, and on [1, 2, 3] the survivor is 3, which occurs once; when no majority is promised, count the candidate again in a second pass.

  • Switching candidates at the wrong moment: test count == 0 before counting x, then count x for its new run. Counting first compares x with the old candidate. With candidate, count = None, 0, the first value subtracts 1, so count becomes -1 and never returns to 0. Then [3, 1, 3] returns None.

  • Skipping the last value: a loop over nums[:-1] never counts it, and [1, 2, 2] returns 1.

  • Returning the early leader: the candidate with the largest count so far is not the answer; the lead changes, and only the value standing at the end counts.

  • Counting every value: a hash map of counts is correct and O(N) time, but it uses O(N) extra space; the follow-up asks for O(1), which is what the pairing-off gives.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

One value takes up "more than half of the positions", "every input is built so that such a value exists", and the follow-up asks for "only O(1) extra space": no count per value is allowed, and a value that holds more than half can't be cancelled out by all the others together. That is Boyer-Moore Voting.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Decision rule: if count == 0: candidate = x, then count += 1 if x == candidate else -1; return candidate after the last x.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Reading count as how often candidate occurs: it counts only the copies not paired off, so on [2,2,1,1,1,2,2] it ends at 1, not 4.

The 60-Second Interview Pitch

Say this out loud before you type a single line

I'd use Boyer-Moore Voting. The majority fills more than half the array, so if every value cancels one copy of a different value, the majority still has copies left over. I keep two variables: a candidate and a count of its copies that haven't been cancelled yet. For each value, if the count is zero, that value becomes the candidate; then a match adds one to the count and a different value subtracts one. Each subtraction removes two different values, at most one of them the majority, so the majority can't be paired off completely, and it's the candidate at the end. The trap is trusting the candidate too early or without a guarantee: in the middle of the example the candidate is the wrong value, and on an array with no majority the survivor means nothing, so there I'd count it in a second pass. One pass, O(N) time, O(1) space.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

Look at the code: for x in nums runs N times, and each round does one comparison count == 0, at most one assignment candidate = x, one comparison x == candidate and one addition. That is O(1) per value, so the pass is O(N). There is no second pass, because the input promises a majority.

SPACE COMPLEXITY

O(1)

candidate and count are two variables whatever N is: O(1) extra space. The answer is one integer.

Formal Recurrence Relation

T(N) = N · O(1) = O(N)

Derivation Progression

Setup

O(1)

candidate, count = None, 0.

The pass

N · O(1)

for x in nums: one count == 0 test, at most one assignment, one x == candidate test and one addition per value.

Total

O(N)

One pass, constant work per value, no verification pass (a majority is promised).

Variable Definitions

NNN

Number of values, len(nums) (at most 5 * 104)

Memory Architecture & Bounds

🟣 Call Stack

O(1) Iterative, no recursion

🔵 Auxiliary Heap

O(1): candidate and count

🟢 Output Space

O(1): one integer

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N): every value is read once

Average Case

O(N)O(N)O(N)

Worst Case

O(N)O(N)O(N): the same single pass

Pointer Invariant Transition Progression

Pointer Invariant Transition Progression
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "more than half of the positions", "only O(1) extra space". A value that holds more than half of the input, found without a count per value: Boyer-Moore Voting, pairing off different values.

CONSTRAINTS & BOUNDS

N≤5⋅104N \le 5 \cdot 10^4N≤5⋅104 values in [−109,109][-10^9, 10^9][−109,109]. A hash map of counts is O(N)O(N)O(N) time but O(N)O(N)O(N) memory, and sorting is O(Nlog⁡N)O(N \log N)O(NlogN); voting is one pass with two variables: O(N)O(N)O(N) time, O(1)O(1)O(1) space.

FAANG PRODUCTION TRAPS & EDGE CASES

When shards merge, different candidates must cancel (larger count minus smaller), never add: adding would let a value that is not the majority collect votes it never had. On a stream, keep the data replayable if the majority is not guaranteed, because the check needs a second look.

Theory Context•Two Pointers & Sliding Window
EasyLC 169

Majority Element (LeetCode 169)

Target Frequency:AmazonGoogleMicrosoft

In an integer array nums of length n, one value takes up more than half of the positions: it occurs more than ⌊n / 2⌋ times, and every input is built so that such a value exists. That value is called the majority element. Return it.

Follow-up: can you find it in linear time with only O(1) extra space?

Worked Examples

Example 1
Input:nums = [3,2,3]
Output:3
30213233: 2 of 3
Explanation: n = 3, so the majority needs more than 1 copy. 3 occurs twice.
Example 2
Input:nums = [2,2,1,1,1,2,2]
Output:2
202112131425261 leads here2 wins: 4 of 7
Explanation: n = 7, so the majority needs more than 3 copies. 2 occurs four times and 1 three times.

⚖️Formal Constraints & Bounds

  • n == nums.length

  • 1 <= n <= 5 * 104

  • -109 <= nums[i] <= 109

  • The input is generated such that a majority element will exist in the array.

Deep-Dive & Conceptual Insights

Core Insight

Cancel each value against a different one: a value that fills more than half the array has more copies than all the others together, so some of its copies are still standing when the values run out.

Real-World Scenario & Production Applications

A cluster of replicas votes on a value, and more than half of them are known to agree; a stream of events is known to be dominated by one source. Counting every value needs memory that grows with the number of distinct values. Pairing off disagreeing values needs two variables, whatever the input size, and still finds the value that holds more than half.

Step-by-Step Execution Trace Table

Example 2, nums = [2,2,1,1,1,2,2] (the debugger's first preset; the trap is the step where 1 becomes the candidate):

xcount == 0 before x?candidatecount afterWhat happened
2yes212 starts a run
2no22a second copy of 2
1no211 cancels one 2
1no201 cancels the other 2: the first four values are paired off
1yes111 becomes the candidate, but 1 is not the majority: a candidate is only a survivor so far
2no102 cancels the 1
2yes212 starts the last run
endreturn candidate gives 2
Worked on Paper

The Math, Step by Step

1. The counts the code relies on

Let nnn be the length of nums, and let mmm be the majority value. The problem guarantees that mmm occurs more than ⌊n/2⌋\lfloor n / 2 \rfloor⌊n/2⌋ times. So mmm occurs more often than all other values together:

copies of m  >  copies of all other values\text{copies of } m \;>\; \text{copies of all other values}copies of m>copies of all other values

The code keeps two variables. candidate is a value, and count is the number of copies of candidate that are not yet cancelled.

2. One step: an element either adds a copy or cancels one

For each element x, one of three things happens:

CaseWhat the code doesMeaning
count == 0candidate = x, then count becomes 1nothing is left over, so x starts a new candidate
x == candidatecount += 1one more uncancelled copy of the candidate
x != candidatecount -= 1x and one copy of the candidate cancel each other

Each cancellation removes a pair of two different values: x and one earlier copy of the candidate. After any prefix of nums, the elements seen so far split into cancelled pairs of different values, plus count copies of candidate that are left over.

3. Why the majority is the candidate at the end

Every cancelled pair holds two different values, so it holds at most one copy of mmm. So each copy of mmm inside a pair uses up one element that is not mmm. The elements that are not mmm number fewer than the copies of mmm. So the pairs cannot use up every copy of mmm. At least one copy of mmm is left over at the end.

The left-over elements are all copies of candidate. At least one of them is mmm, so candidate is mmm, and count is at least 1. This argument is the Boyer-Moore voting algorithm.

The argument needs the guarantee of part 1. Without a majority, the final candidate can be any value. For example, [1, 2, 3] ends with candidate 3, which is not a majority. The problem promises a majority, so the code does not check it.

4. When count is 0

count == 0 means every element seen so far is inside a cancelled pair. The next element starts a new candidate. The order inside the loop matters. The code first sets candidate = x and then runs count += 1 if x == candidate else -1. Because x now equals candidate, count becomes 1. So count never drops below 0.

A candidate can change many times, as in Example 2. The only thing that matters is the candidate after the last element.

5. Example 2 by hand

nums = [2,2,1,1,1,2,2], so n=7n = 7n=7. The value 2 occurs 4 times, more than ⌊7/2⌋=3\lfloor 7 / 2 \rfloor = 3⌊7/2⌋=3.

xcount == 0 before?candidatecount afterWhat happened
2yes21new candidate 2
2no22one more 2
1no21this 1 cancels one 2
1no20this 1 cancels the other 2
1yes11new candidate 1
2no10this 2 cancels the 1
2yes21new candidate 2

The cancelled pairs are (2, 1), (2, 1) and (1, 2). Each holds one 2 and one 1. The left-over element is the last 2. The code returns 2, the expected output.

6. Example 1 by hand

nums = [3,2,3]. The first 3 becomes the candidate with count = 1. The 2 cancels it, so count is 0. The last 3 starts a new candidate with count = 1. The code returns 3, the expected output.

7. From the math to the code
MathIn majorityElement
nothing seen, nothing left overcandidate, count = None, 0
everything so far is cancelledif count == 0: followed by candidate = x
one more left-over copycount += 1 when x == candidate
a pair of different values cancelscount -= 1 when x != candidate
the left-over value is the majorityreturn candidate

The loop reads each element once, so the code takes O(n)O(n)O(n) time. It keeps two variables, so it uses O(1)O(1)O(1) extra space.

Code Shape
Archetype Code Shape
Python
1A value that fills more than half of `nums` has more copies than all the other values together: if each value cancels one copy of a different value, the majority still has copies left.
2Keep this true: before each `x`, the values read so far, except `count` copies of `candidate`, split into pairs of different values. When `count == 0`, everything so far is paired off.
3The shape: one loop over `nums` with two steps per value: first decide whether a new run starts, then update `count`. After the loop, return the value that is left standing.
4The trap: the survivor is only a candidate. Here it is safe to return because a majority is promised; in the middle of `[2,2,1,1,1,2,2]` the candidate is `1`, and without the promise you must count it again.

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

Counting every value works, but it needs memory for every distinct value. Boyer-Moore Voting needs two variables. Picture each value cancelling one copy of a different value: two different values leave together. The majority fills more than half of nums, so even if every other value cancels one of its copies, some copies are left. The code keeps only what hasn't been cancelled yet: candidate and count, the number of its copies still unpaired. A matching x adds a copy, a different x cancels one, and when count reaches 0 the next x becomes the new candidate.

🗳️ The Analogy: A Shouting Match in a Room

People from several parties walk into a room one at a time. Whenever someone meets a supporter of a different party already standing there, the two of them leave together. Supporters of the same party stay and wait. If one party brought more than half of all the people, the others can't pair off all of them: when the door closes, the people still standing belong to that party. You only ever need to remember which party is standing and how many of its people are there.

🔑 Why It Works

Before each x, the values already read, except count copies of candidate, can be split into pairs of different values. Each pair holds at most one copy of the majority, and there are fewer other values than copies of the majority, so the pairs can't use up all of its copies: it must be the value left standing at the end. The trap: that is a promise about the end only, and only because a majority exists. In the middle of [2,2,1,1,1,2,2] the candidate is 1, and on [1, 2, 3] the survivor is 3, which occurs once; when a majority is not promised, count the survivor again.

  • Trusting the survivor without a promise (the trap): return candidate is right here only because a majority exists. In the middle of [2,2,1,1,1,2,2] the candidate is 1, and on [1, 2, 3] the survivor is 3, which occurs once; when no majority is promised, count the candidate again in a second pass.

  • Switching candidates at the wrong moment: test count == 0 before counting x, then count x for its new run. Counting first compares x with the old candidate. With candidate, count = None, 0, the first value subtracts 1, so count becomes -1 and never returns to 0. Then [3, 1, 3] returns None.

  • Skipping the last value: a loop over nums[:-1] never counts it, and [1, 2, 2] returns 1.

  • Returning the early leader: the candidate with the largest count so far is not the answer; the lead changes, and only the value standing at the end counts.

  • Counting every value: a hash map of counts is correct and O(N) time, but it uses O(N) extra space; the follow-up asks for O(1), which is what the pairing-off gives.

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

One value takes up "more than half of the positions", "every input is built so that such a value exists", and the follow-up asks for "only O(1) extra space": no count per value is allowed, and a value that holds more than half can't be cancelled out by all the others together. That is Boyer-Moore Voting.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Decision rule: if count == 0: candidate = x, then count += 1 if x == candidate else -1; return candidate after the last x.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Reading count as how often candidate occurs: it counts only the copies not paired off, so on [2,2,1,1,1,2,2] it ends at 1, not 4.

The 60-Second Interview Pitch

Say this out loud before you type a single line

I'd use Boyer-Moore Voting. The majority fills more than half the array, so if every value cancels one copy of a different value, the majority still has copies left over. I keep two variables: a candidate and a count of its copies that haven't been cancelled yet. For each value, if the count is zero, that value becomes the candidate; then a match adds one to the count and a different value subtracts one. Each subtraction removes two different values, at most one of them the majority, so the majority can't be paired off completely, and it's the candidate at the end. The trap is trusting the candidate too early or without a guarantee: in the middle of the example the candidate is the wrong value, and on an array with no majority the survivor means nothing, so there I'd count it in a second pass. One pass, O(N) time, O(1) space.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N)

Look at the code: for x in nums runs N times, and each round does one comparison count == 0, at most one assignment candidate = x, one comparison x == candidate and one addition. That is O(1) per value, so the pass is O(N). There is no second pass, because the input promises a majority.

SPACE COMPLEXITY

O(1)

candidate and count are two variables whatever N is: O(1) extra space. The answer is one integer.

Formal Recurrence Relation

T(N) = N · O(1) = O(N)

Derivation Progression

Setup

O(1)

candidate, count = None, 0.

The pass

N · O(1)

for x in nums: one count == 0 test, at most one assignment, one x == candidate test and one addition per value.

Total

O(N)

One pass, constant work per value, no verification pass (a majority is promised).

Variable Definitions

NNN

Number of values, len(nums) (at most 5 * 104)

Memory Architecture & Bounds

🟣 Call Stack

O(1) Iterative, no recursion

🔵 Auxiliary Heap

O(1): candidate and count

🟢 Output Space

O(1): one integer

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N): every value is read once

Average Case

O(N)O(N)O(N)

Worst Case

O(N)O(N)O(N): the same single pass

Pointer Invariant Transition Progression

Pointer Invariant Transition Progression
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "more than half of the positions", "only O(1) extra space". A value that holds more than half of the input, found without a count per value: Boyer-Moore Voting, pairing off different values.

CONSTRAINTS & BOUNDS

N≤5⋅104N \le 5 \cdot 10^4N≤5⋅104 values in [−109,109][-10^9, 10^9][−109,109]. A hash map of counts is O(N)O(N)O(N) time but O(N)O(N)O(N) memory, and sorting is O(Nlog⁡N)O(N \log N)O(NlogN); voting is one pass with two variables: O(N)O(N)O(N) time, O(1)O(1)O(1) space.

FAANG PRODUCTION TRAPS & EDGE CASES

When shards merge, different candidates must cancel (larger count minus smaller), never add: adding would let a value that is not the majority collect votes it never had. On a stream, keep the data replayable if the majority is not guaranteed, because the check needs a second look.

© 2026 Hi👋WebEnterprise. All rights reserved.
Sitemap•llms.txt•