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•Priority Queue / Heap
MediumLC 767

Reorganize String (LeetCode 767)

Target Frequency:GoogleMetaAmazon

You're given a string s. Reorder its characters so that no two characters sitting next to each other are the same.

Return any ordering that satisfies this, or return an empty string "" if no such ordering exists.

Worked Examples

Example 1
Input:s = "aab"
Output:"aba"
Explanation: Putting b between the two as keeps equal letters apart.
Example 2
Input:s = "aaab"
Output:""
Explanation: Three as need at least two other letters to separate them, but there is only one b, so no arrangement works.

⚖️Formal Constraints & Bounds

  • 1 <= s.length <= 500

  • s consists of lowercase English letters.

Deep-Dive & Conceptual Insights

Core Insight

Greedily consuming highest-frequency characters with a 1-step buffer guarantees conflict-free interleaving.

Real-World Scenario & Production Applications

Task round-robin interleaving, distributed cluster resource anti-affinity scheduling.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Character Frequency Max-Heap Seeding

Count every character's frequency and push (-count, char) for each into a max-heap (negated for Python's min-heap). If any character's count exceeds ceil(len(s) / 2), no valid rearrangement exists.

Mathematical Recurrence / Code Invariant
freq = Counter(s)
if max(freq.values()) > (len(s) + 1) // 2:
    return ""
heap = [(-count, ch) for ch, count in freq.items()]
heapify(heap)

Step-by-Step Execution Trace Table

StepHeap State (Freq, Char)Chosen CharBuffered PreviousResult String
1[(2, 'a'), (1, 'b')]'a'(1, 'a')'a'
2[(1, 'b')]'b'Re-push 'a''ab'
3[(1, 'a')]'a'None'aba'
Code Shape
Archetype Code Shape
Python
1counts = Counter(s)
2max_heap = [(-cnt, ch) for ch, cnt in counts.items()]
3heapify(max_heap)
4prev_cnt, prev_ch = 0, ''
5result = []
6while max_heap:
7 cnt, ch = heappop(max_heap)
8 result.append(ch)
9 if prev_cnt < 0:
10 heappush(max_heap, (prev_cnt, prev_ch))
11 prev_cnt, prev_ch = cnt + 1, ch
12res_str = ''.join(result)
13return res_str if len(res_str) == len(s) else ''

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition
Code / Blueprint
Arranging characters so that no two adjacent characters are identical is a greedy scheduling problem. If any character's frequency exceeds $\lceil N/2 \rceil$, the Pigeonhole Principle proves an arrangement is impossible. Otherwise, we greedily place the character with the highest remaining frequency, holding it in a temporary cooldown buffer for one step so it cannot be placed next to itself, then re-enqueuing it into the max-heap.
 
🎪 The Analogy: Seating Departments So No Two From the Same Team Sit Together

Imagine seating people from several departments in a row so no two people from the same department ever sit next to each other. Greedily seat someone from whichever department currently has the most people left unseated — that department is the most "constrained," so give it priority now, while you still have the most flexibility. But immediately after seating them, put that department on a one-seat cooldown: it cannot be selected again until one more person (from a different department) has been seated first.

🔑 The Key Idea in the Code

Holding the just-used character out of the heap for exactly one iteration — instead of pushing it straight back — is the entire "cooldown" mechanism, implemented with zero extra data structures beyond the heap itself.

  • Impossible arrangement condition: If any character has frequency >(N+1)//2> (N + 1) // 2>(N+1)//2, pigeonhole principle proves adjacent identical characters cannot be avoided; return '' immediately.

  • Pushing previously used character back into heap immediately: Re-inserting the character into the max-heap before popping the next character causes the same character to be chosen twice in a row. Hold it in a temporary variable and only push it back on the next iteration.

  • Character count parity on odd string lengths: For odd NNN, the most frequent character can appear at most (N+1)//2(N + 1) // 2(N+1)//2 times and must occupy the even indices (0, 2, 4, ...).

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Rearranging characters/tasks to prevent adjacent identical elements.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: most frequent remaining character is always prioritized.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Pigeonhole violation: if max frequency > (len(s) + 1) // 2, valid rearrangement is impossible.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I'd use Most Frequent First. I count the characters and put them in a max-heap by count, stored negated because Python's heap is a min-heap. Each step I pop the character with the most copies left and append it. The character I placed last waits in a one-slot holding buffer and only goes back into the heap after the next character is placed, so the same character can never land twice in a row. Placing the biggest pile first keeps it from being stranded at the end. The trap is pushing the held character back before popping the next one: I would just pick it again. If the heap runs empty while a character still waits, the result is shorter than s and I return an empty string. That is O(N log A) time and O(A) space for an alphabet of size A."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N log A)

Counting reads all N characters once: O(N). The loop then runs once per character of s (at most N times). Each pass does one heappop and at most one heappush (the held character going back), on a heap of at most A entries, so each pass is O(log A). Joining result is O(N). Total O(N log A), which is O(N) for the 26 lowercase letters of this problem.

SPACE COMPLEXITY

O(A)

counts and max_heap hold one entry per distinct character, O(A). The holding buffer prev_cnt, prev_ch is O(1). No recursion. The output string itself is O(N) and is not counted as auxiliary space.

Formal Recurrence Relation

T(N) = O(N) + N · O(log A) = O(N log A)

Derivation Progression

Count

Counter(s) ⟹ O(N)

Reads every character once; heapify of at most A pairs is O(A).

Pop, place, release

≤ N loop passes × O(log A)

Each pass pops the most frequent allowed character and pushes back at most the held one.

Join and check

O(N)

"".join(result) and the length test that detects a stuck arrangement.

Variable Definitions

NNN

Length of the input string

AAA

Alphabet size: distinct characters in s (at most 26 lowercase English letters here)

Memory Architecture & Bounds

🟣 Call Stack

O(1) Iterative

🔵 Auxiliary Heap

O(A) counts and max-heap, plus the O(1) holding buffer

🟢 Output Space

O(N) Reorganized string (not counted as auxiliary)

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N): the count always reads the whole string; an impossible input only stops the heap loop early.

Average Case

O(Nlog⁡A)O(N \log A)O(NlogA).

Worst Case

O(Nlog⁡A)O(N \log A)O(NlogA) for a valid arrangement.

Binary Heap Priority Queue Tree

Binary Heap Priority Queue Tree
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "reorganize string so that no two adjacent characters are the same", "return empty string if not possible". Equal items must be kept apart and the biggest pile is the hardest to place, so a Most Frequent First max-heap with a one-slot holding buffer builds the answer.

CONSTRAINTS & BOUNDS

1≤s.length≤5001 \le s.length \le 5001≤s.length≤500, lowercase English letters only, so A≤26A \le 26A≤26. Time budget O(Nlog⁡A)O(N \log A)O(NlogA), which is O(N)O(N)O(N) here.

FAANG PRODUCTION TRAPS & EDGE CASES

The failure test is at the end (len(res_str) == len(s)), so a stuck input still reads the whole string once to count it.

Core Algorithmic State Invariants

  1. The Heap Is Sized by the Alphabet

max_heap holds one (-count, char) pair per distinct character, never one per position. With lowercase letters that is at most 26 entries, so each pop or push is effectively constant; with a large alphabet of A distinct values, each costs O(log A).

Theory Context•Priority Queue / Heap
MediumLC 767

Reorganize String (LeetCode 767)

Target Frequency:GoogleMetaAmazon

You're given a string s. Reorder its characters so that no two characters sitting next to each other are the same.

Return any ordering that satisfies this, or return an empty string "" if no such ordering exists.

Worked Examples

Example 1
Input:s = "aab"
Output:"aba"
Explanation: Putting b between the two as keeps equal letters apart.
Example 2
Input:s = "aaab"
Output:""
Explanation: Three as need at least two other letters to separate them, but there is only one b, so no arrangement works.

⚖️Formal Constraints & Bounds

  • 1 <= s.length <= 500

  • s consists of lowercase English letters.

Deep-Dive & Conceptual Insights

Core Insight

Greedily consuming highest-frequency characters with a 1-step buffer guarantees conflict-free interleaving.

Real-World Scenario & Production Applications

Task round-robin interleaving, distributed cluster resource anti-affinity scheduling.

Subproblems & Recurrence Decomposition3 Phases

🧩Subproblem 1: Character Frequency Max-Heap Seeding

Count every character's frequency and push (-count, char) for each into a max-heap (negated for Python's min-heap). If any character's count exceeds ceil(len(s) / 2), no valid rearrangement exists.

Mathematical Recurrence / Code Invariant
freq = Counter(s)
if max(freq.values()) > (len(s) + 1) // 2:
    return ""
heap = [(-count, ch) for ch, count in freq.items()]
heapify(heap)

Step-by-Step Execution Trace Table

StepHeap State (Freq, Char)Chosen CharBuffered PreviousResult String
1[(2, 'a'), (1, 'b')]'a'(1, 'a')'a'
2[(1, 'b')]'b'Re-push 'a''ab'
3[(1, 'a')]'a'None'aba'
Code Shape
Archetype Code Shape
Python
1counts = Counter(s)
2max_heap = [(-cnt, ch) for ch, cnt in counts.items()]
3heapify(max_heap)
4prev_cnt, prev_ch = 0, ''
5result = []
6while max_heap:
7 cnt, ch = heappop(max_heap)
8 result.append(ch)
9 if prev_cnt < 0:
10 heappush(max_heap, (prev_cnt, prev_ch))
11 prev_cnt, prev_ch = cnt + 1, ch
12res_str = ''.join(result)
13return res_str if len(res_str) == len(s) else ''

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition
Code / Blueprint
Arranging characters so that no two adjacent characters are identical is a greedy scheduling problem. If any character's frequency exceeds $\lceil N/2 \rceil$, the Pigeonhole Principle proves an arrangement is impossible. Otherwise, we greedily place the character with the highest remaining frequency, holding it in a temporary cooldown buffer for one step so it cannot be placed next to itself, then re-enqueuing it into the max-heap.
 
🎪 The Analogy: Seating Departments So No Two From the Same Team Sit Together

Imagine seating people from several departments in a row so no two people from the same department ever sit next to each other. Greedily seat someone from whichever department currently has the most people left unseated — that department is the most "constrained," so give it priority now, while you still have the most flexibility. But immediately after seating them, put that department on a one-seat cooldown: it cannot be selected again until one more person (from a different department) has been seated first.

🔑 The Key Idea in the Code

Holding the just-used character out of the heap for exactly one iteration — instead of pushing it straight back — is the entire "cooldown" mechanism, implemented with zero extra data structures beyond the heap itself.

  • Impossible arrangement condition: If any character has frequency >(N+1)//2> (N + 1) // 2>(N+1)//2, pigeonhole principle proves adjacent identical characters cannot be avoided; return '' immediately.

  • Pushing previously used character back into heap immediately: Re-inserting the character into the max-heap before popping the next character causes the same character to be chosen twice in a row. Hold it in a temporary variable and only push it back on the next iteration.

  • Character count parity on odd string lengths: For odd NNN, the most frequent character can appear at most (N+1)//2(N + 1) // 2(N+1)//2 times and must occupy the even indices (0, 2, 4, ...).

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

Rearranging characters/tasks to prevent adjacent identical elements.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

Invariant: most frequent remaining character is always prioritized.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • Pigeonhole violation: if max frequency > (len(s) + 1) // 2, valid rearrangement is impossible.

The 60-Second Interview Pitch

Say this out loud before you type a single line

"I'd use Most Frequent First. I count the characters and put them in a max-heap by count, stored negated because Python's heap is a min-heap. Each step I pop the character with the most copies left and append it. The character I placed last waits in a one-slot holding buffer and only goes back into the heap after the next character is placed, so the same character can never land twice in a row. Placing the biggest pile first keeps it from being stranded at the end. The trap is pushing the held character back before popping the next one: I would just pick it again. If the heap runs empty while a character still waits, the result is shorter than s and I return an empty string. That is O(N log A) time and O(A) space for an alphabet of size A."

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N log A)

Counting reads all N characters once: O(N). The loop then runs once per character of s (at most N times). Each pass does one heappop and at most one heappush (the held character going back), on a heap of at most A entries, so each pass is O(log A). Joining result is O(N). Total O(N log A), which is O(N) for the 26 lowercase letters of this problem.

SPACE COMPLEXITY

O(A)

counts and max_heap hold one entry per distinct character, O(A). The holding buffer prev_cnt, prev_ch is O(1). No recursion. The output string itself is O(N) and is not counted as auxiliary space.

Formal Recurrence Relation

T(N) = O(N) + N · O(log A) = O(N log A)

Derivation Progression

Count

Counter(s) ⟹ O(N)

Reads every character once; heapify of at most A pairs is O(A).

Pop, place, release

≤ N loop passes × O(log A)

Each pass pops the most frequent allowed character and pushes back at most the held one.

Join and check

O(N)

"".join(result) and the length test that detects a stuck arrangement.

Variable Definitions

NNN

Length of the input string

AAA

Alphabet size: distinct characters in s (at most 26 lowercase English letters here)

Memory Architecture & Bounds

🟣 Call Stack

O(1) Iterative

🔵 Auxiliary Heap

O(A) counts and max-heap, plus the O(1) holding buffer

🟢 Output Space

O(N) Reorganized string (not counted as auxiliary)

Boundary Best / Worst Cases

Best Case

O(N)O(N)O(N): the count always reads the whole string; an impossible input only stops the heap loop early.

Average Case

O(Nlog⁡A)O(N \log A)O(NlogA).

Worst Case

O(Nlog⁡A)O(N \log A)O(NlogA) for a valid arrangement.

Binary Heap Priority Queue Tree

Binary Heap Priority Queue Tree
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "reorganize string so that no two adjacent characters are the same", "return empty string if not possible". Equal items must be kept apart and the biggest pile is the hardest to place, so a Most Frequent First max-heap with a one-slot holding buffer builds the answer.

CONSTRAINTS & BOUNDS

1≤s.length≤5001 \le s.length \le 5001≤s.length≤500, lowercase English letters only, so A≤26A \le 26A≤26. Time budget O(Nlog⁡A)O(N \log A)O(NlogA), which is O(N)O(N)O(N) here.

FAANG PRODUCTION TRAPS & EDGE CASES

The failure test is at the end (len(res_str) == len(s)), so a stuck input still reads the whole string once to count it.

Core Algorithmic State Invariants

  1. The Heap Is Sized by the Alphabet

max_heap holds one (-count, char) pair per distinct character, never one per position. With lowercase letters that is at most 26 entries, so each pop or push is effectively constant; with a large alphabet of A distinct values, each costs O(log A).

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