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•Depth-First Search (DFS)
MediumLC 652

Find Duplicate Subtrees (LeetCode 652)

The input is one binary tree, passed as its root. A subtree is a node together with all the nodes below it. Two subtrees are duplicates when they have the same shape and the same value at every position.

Some shapes appear more than once in the tree. Find every shape that appears at least twice. For each such shape, report the root of one of its copies, not the root of every copy.

Worked Examples

Example 1
Input:root = [1,2,3,4,null,2,4,null,null,4]
Output:[[2,4],[4]]
4214234
Explanation: The node 2 with a left child 4 appears twice, and the single node 4 appears three times. Each shape is reported once. The function on this page returns [2, 4].
Example 2
Input:root = [2,1,1]
Output:[[1]]
121
Explanation: The two leaves with value 1 are the same shape. The function on this page returns [1].
Example 3
Input:root = [2,2,2,3,null,3,null]
Output:[[2,3],[3]]
32232
Explanation: Both children of the root are a node 2 with a left child 3, and the two leaves 3 are the same shape. The function on this page returns [2, 3].

⚖️Formal Constraints & Bounds

  • The number of nodes in the tree is in the range [1, 5000].

  • -200 <= Node.val <= 200

Deep-Dive & Conceptual Insights

Core Insight

Write each subtree as one string made of its value and the strings of its two children, with # for a missing child. Two subtrees are the same exactly when their strings are the same, so counting the strings finds every repeated shape in one pass.

Real-World Scenario & Production Applications

A tool that removes duplicate folders from a file system, or a compiler that stores each repeated piece of a syntax tree only once, must find the parts of a tree that are exactly the same. It writes each part as a short text key, and then it compares keys instead of comparing whole parts again and again.

Step-by-Step Execution Trace Table

Example 3, root = [2,2,2,3,null,3,null], one row for each node, in the order key_of finishes them. A missing child returns "#" and is not listed.

StepNodekeyseen[key]repeated
1the left leaf 33,#,#1[]
2the left 22,3,#,#,#1[]
3the right leaf 33,#,#2[3]
4the right 22,3,#,#,#2[3, 2]
5the root 22,2,3,#,#,#,2,3,#,#,#1[3, 2]
Endsorted(repeated) = [2, 3]

At steps 3 and 4, the key was already in seen, so its count reached 2 and the root value was recorded once.

Trace Inputroot = [1,2,3,4,null,2,4,null,null,4]
Expected[[2,4],[4]]

Example 3, root = [2,2,2,3,null,3,null], one row for each node, in the order key_of finishes them. A missing child returns "#" and is not listed.

StepNodekeyseen[key]repeated
1the left leaf 33,#,#1[]
2the left 22,3,#,#,#1[]
3the right leaf 33,#,#2[3]
4the right 22,3,#,#,#2[3, 2]
5the root 22,2,3,#,#,#,2,3,#,#,#1[3, 2]
Endsorted(repeated) = [2, 3]

At steps 3 and 4, the key was already in seen, so its count reached 2 and the root value was recorded once.

Code Shape
Archetype Code Shape
Python
1A subtree repeats when another subtree has the same shape and the same values, so give every subtree a string that is equal for equal subtrees: `key_of(node)`.
2A key is built after both children return: `key = f"{node.val},{left_key},{right_key}"`, with `#` for a missing child.
3Count the keys: `seen[key] = seen.get(key, 0) + 1`, and record the root value when `seen[key] == 2`.
4The trap: leave nothing out of the key. Without the `#` for a missing child, a node with only a left child `2` and a node with only a right child `2` give the same text.

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

Bottom-Up DFS lets every subtree hand its parent one finished answer. Some questions compare the subtrees of one tree with each other: which shapes appear twice, or whether one tree appears inside another. Comparing two subtrees directly means walking both of them every time. Tree as a String gives every subtree a name instead. key_of(node) returns a string built from node.val and the strings of its two children, so two subtrees have the same string exactly when they have the same shape and the same values. Then the subtrees are counted, grouped or compared by their strings.

🏢 The Analogy: Labels on Nested Boxes

Every box holds a number and two smaller boxes, and either of them can be empty. A clerk writes a label for each box: the number, then the label of the left box, then the label of the right box, with a # for an empty place. The clerk writes the label of a box only after both smaller boxes have labels. Two boxes with the same label hold the same contents, so the clerk finds the repeated boxes by counting labels.

🔑 Why It Works

key = f"{node.val},{left_key},{right_key}" always has the value first, the left key second and the right key third, so a position in the key always means one position in the tree. The # marks a missing child, so a node with only a left child and a node with only a right child get different keys. seen[key] counts each key, and if seen[key] == 2: records a shape once, at its second sighting.

  • Leaving a missing child out of the key

  • Joining the parts of the key without separators

  • Reporting a shape every time it is seen again

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

"Duplicate subtrees" with "the same structure with the same node values": the question compares the subtrees of one tree with each other, so each subtree needs a name that is equal for equal subtrees. That is the signal for Tree as a String: build a string for every subtree from the strings of its children.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

key_of(node) returns f"{node.val},{left_key},{right_key}", with # for a missing child. Two subtrees have the same key exactly when they have the same shape and the same values. seen[key] counts the subtrees with each key, and repeated gets a root value when seen[key] == 2.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • The card's trap: a key must keep a # for every missing child. A key that skips the missing child gives 1,2 to a node with only a left child 2 and to a node with only a right child 2. On [0,1,1,2,null,null,2] the answer must be [2], not [1, 2].

  • Join the parts with commas: without them, a node 1 over a left child 11 and a node 11 over a left child 1 both give 111###. On [0,1,11,11,null,1] the answer must be [].

  • Record a shape when seen[key] == 2, not seen[key] >= 2: on [1,2,2,3,3,3,3] the leaf shape 3 appears four times and must be reported once.

The 60-Second Interview Pitch

Say this out loud before you type a single line

I'd use Tree as a String. The question compares subtrees of one tree with each other, so every subtree needs a name that is the same for equal subtrees. I write key of node. It asks the left child and the right child for their keys first, and then it joins the node's value with those two keys, with commas between them, into one string. A missing child returns a hash mark, so every key has a place for both children. Then two subtrees have the same key exactly when they have the same shape and the same values. I count each key in a dictionary, and when a count reaches two I record the root value, so each repeated shape is reported once. Every key is as long as its subtree, so on a chain the time and space are O of N squared. The trap I avoid is leaving out the hash mark for a missing child, which makes a left child and a right child look the same.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N^2)

Look at the code: key_of is called once for each node and once for each missing child, so there are at most 2 * N + 1 calls. Building key copies the two child keys, and a key is as long as its subtree, so a node with s nodes in its subtree costs O(s). Reading key to update seen costs O(s) too. The sizes of all subtrees add up to at most N * (N + 1) / 2, which happens on a chain, so the total is O(N^2). On a balanced tree the sizes add up to O(N log N).

SPACE COMPLEXITY

O(N^2)

seen stores one key for each different shape. The longest keys are as long as the whole tree, so on a chain the keys add up to O(N^2) characters. The recursion goes one level deeper for each level of the tree: O(H) frames. repeated holds at most N values.

Formal Recurrence Relation

T(N)=∑vO(size(v))≤N(N+1)2⋅O(1)=O(N2)T(N) = \sum_{v} O(\text{size}(v)) \le \frac{N(N+1)}{2} \cdot O(1) = O(N^2)T(N)=∑v​O(size(v))≤2N(N+1)​⋅O(1)=O(N2)

Derivation Progression

Calls

at most 2N + 1

One call for each node and one call for each missing child.

Work per node

O(size(v))

Joining the value with the two child keys copies the whole key, and reading it for seen costs the same.

Total

O(N^2)

The subtree sizes add up to N(N+1)/2 on a chain, and to O(N log N) on a balanced tree.

Variable Definitions

NNN

Number of nodes in the tree

size(v)size(v)size(v)

Number of nodes in the subtree of node v, which is also the length of its key up to the length of one value

HHH

Height of the tree: the recursion never goes deeper

Memory Architecture & Bounds

🟣 Call Stack

O(H): one frame for each level of the path from the root to the current node

🔵 Auxiliary Heap

O(N^2): seen stores a key for each different shape, and the keys add up to O(N^2) characters on a chain

🟢 Output Space

O(N): repeated holds at most N values

Boundary Best / Worst Cases

Best Case

O(Nlog⁡N)O(N \log N)O(NlogN) on a balanced tree: the subtree sizes add up to Nlog⁡NN \log NNlogN.

Average Case

Between O(Nlog⁡N)O(N \log N)O(NlogN) and O(N2)O(N^2)O(N2): the cost is the sum of the subtree sizes, which grows with the height of the tree.

Worst Case

O(N2)O(N^2)O(N2) time and space on a chain, where the subtree sizes are N,N−1,…,1N, N-1, \dots, 1N,N−1,…,1.

Graph & Tree Traversal Frontier

Graph & Tree Traversal Frontier
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "duplicate subtrees", "the same structure with the same node values". Subtrees of one tree compared with each other: Tree as a String, where every subtree gets a key that is equal for equal subtrees.

CONSTRAINTS & BOUNDS

1≤N≤50001 \le N \le 50001≤N≤5000 nodes and values in [−200,200][-200, 200][−200,200]. Comparing every pair of subtrees node by node is up to N2/2N^2 / 2N2/2 pairs of O(N)O(N)O(N) work each. One bottom-up pass does O(N)O(N)O(N) calls, and each key is as long as its subtree, so the keys add up to O(N2)O(N^2)O(N2) characters on a chain.

FAANG PRODUCTION TRAPS & EDGE CASES

A recursive walk on a chain of 5000 nodes is 5000 calls deep, past CPython's default recursion limit of 1000: raise the limit or use an explicit stack. Every key keeps a # for a missing child and a comma between the parts. Without them, 1,2 stands for both a left child and a right child, and 111### stands for both 1 over 11 and 11 over 1.

Theory Context•Depth-First Search (DFS)
MediumLC 652

Find Duplicate Subtrees (LeetCode 652)

The input is one binary tree, passed as its root. A subtree is a node together with all the nodes below it. Two subtrees are duplicates when they have the same shape and the same value at every position.

Some shapes appear more than once in the tree. Find every shape that appears at least twice. For each such shape, report the root of one of its copies, not the root of every copy.

Worked Examples

Example 1
Input:root = [1,2,3,4,null,2,4,null,null,4]
Output:[[2,4],[4]]
4214234
Explanation: The node 2 with a left child 4 appears twice, and the single node 4 appears three times. Each shape is reported once. The function on this page returns [2, 4].
Example 2
Input:root = [2,1,1]
Output:[[1]]
121
Explanation: The two leaves with value 1 are the same shape. The function on this page returns [1].
Example 3
Input:root = [2,2,2,3,null,3,null]
Output:[[2,3],[3]]
32232
Explanation: Both children of the root are a node 2 with a left child 3, and the two leaves 3 are the same shape. The function on this page returns [2, 3].

⚖️Formal Constraints & Bounds

  • The number of nodes in the tree is in the range [1, 5000].

  • -200 <= Node.val <= 200

Deep-Dive & Conceptual Insights

Core Insight

Write each subtree as one string made of its value and the strings of its two children, with # for a missing child. Two subtrees are the same exactly when their strings are the same, so counting the strings finds every repeated shape in one pass.

Real-World Scenario & Production Applications

A tool that removes duplicate folders from a file system, or a compiler that stores each repeated piece of a syntax tree only once, must find the parts of a tree that are exactly the same. It writes each part as a short text key, and then it compares keys instead of comparing whole parts again and again.

Step-by-Step Execution Trace Table

Example 3, root = [2,2,2,3,null,3,null], one row for each node, in the order key_of finishes them. A missing child returns "#" and is not listed.

StepNodekeyseen[key]repeated
1the left leaf 33,#,#1[]
2the left 22,3,#,#,#1[]
3the right leaf 33,#,#2[3]
4the right 22,3,#,#,#2[3, 2]
5the root 22,2,3,#,#,#,2,3,#,#,#1[3, 2]
Endsorted(repeated) = [2, 3]

At steps 3 and 4, the key was already in seen, so its count reached 2 and the root value was recorded once.

Trace Inputroot = [1,2,3,4,null,2,4,null,null,4]
Expected[[2,4],[4]]

Example 3, root = [2,2,2,3,null,3,null], one row for each node, in the order key_of finishes them. A missing child returns "#" and is not listed.

StepNodekeyseen[key]repeated
1the left leaf 33,#,#1[]
2the left 22,3,#,#,#1[]
3the right leaf 33,#,#2[3]
4the right 22,3,#,#,#2[3, 2]
5the root 22,2,3,#,#,#,2,3,#,#,#1[3, 2]
Endsorted(repeated) = [2, 3]

At steps 3 and 4, the key was already in seen, so its count reached 2 and the root value was recorded once.

Code Shape
Archetype Code Shape
Python
1A subtree repeats when another subtree has the same shape and the same values, so give every subtree a string that is equal for equal subtrees: `key_of(node)`.
2A key is built after both children return: `key = f"{node.val},{left_key},{right_key}"`, with `#` for a missing child.
3Count the keys: `seen[key] = seen.get(key, 0) + 1`, and record the root value when `seen[key] == 2`.
4The trap: leave nothing out of the key. Without the `#` for a missing child, a node with only a left child `2` and a node with only a right child `2` give the same text.

Conceptual Narrative

🧭 Conceptual Foundation & Pattern Intuition

Bottom-Up DFS lets every subtree hand its parent one finished answer. Some questions compare the subtrees of one tree with each other: which shapes appear twice, or whether one tree appears inside another. Comparing two subtrees directly means walking both of them every time. Tree as a String gives every subtree a name instead. key_of(node) returns a string built from node.val and the strings of its two children, so two subtrees have the same string exactly when they have the same shape and the same values. Then the subtrees are counted, grouped or compared by their strings.

🏢 The Analogy: Labels on Nested Boxes

Every box holds a number and two smaller boxes, and either of them can be empty. A clerk writes a label for each box: the number, then the label of the left box, then the label of the right box, with a # for an empty place. The clerk writes the label of a box only after both smaller boxes have labels. Two boxes with the same label hold the same contents, so the clerk finds the repeated boxes by counting labels.

🔑 Why It Works

key = f"{node.val},{left_key},{right_key}" always has the value first, the left key second and the right key third, so a position in the key always means one position in the tree. The # marks a missing child, so a node with only a left child and a node with only a right child get different keys. seen[key] counts each key, and if seen[key] == 2: records a shape once, at its second sighting.

  • Leaving a missing child out of the key

  • Joining the parts of the key without separators

  • Reporting a shape every time it is seen again

Senior SWE Reasoning Architecture

4-Phase Thought Process Model

Pattern Recognition Signals

The 10-second spot

"Duplicate subtrees" with "the same structure with the same node values": the question compares the subtrees of one tree with each other, so each subtree needs a name that is equal for equal subtrees. That is the signal for Tree as a String: build a string for every subtree from the strings of its children.

Formulating the Predicate & Invariants

Turning intuition into a boolean rule

key_of(node) returns f"{node.val},{left_key},{right_key}", with # for a missing child. Two subtrees have the same key exactly when they have the same shape and the same values. seen[key] counts the subtrees with each key, and repeated gets a root value when seen[key] == 2.

Silent Failure Traps & Edge Cases

Where confident candidates still lose points

  • The card's trap: a key must keep a # for every missing child. A key that skips the missing child gives 1,2 to a node with only a left child 2 and to a node with only a right child 2. On [0,1,1,2,null,null,2] the answer must be [2], not [1, 2].

  • Join the parts with commas: without them, a node 1 over a left child 11 and a node 11 over a left child 1 both give 111###. On [0,1,11,11,null,1] the answer must be [].

  • Record a shape when seen[key] == 2, not seen[key] >= 2: on [1,2,2,3,3,3,3] the leaf shape 3 appears four times and must be reported once.

The 60-Second Interview Pitch

Say this out loud before you type a single line

I'd use Tree as a String. The question compares subtrees of one tree with each other, so every subtree needs a name that is the same for equal subtrees. I write key of node. It asks the left child and the right child for their keys first, and then it joins the node's value with those two keys, with commas between them, into one string. A missing child returns a hash mark, so every key has a place for both children. Then two subtrees have the same key exactly when they have the same shape and the same values. I count each key in a dictionary, and when a count reaches two I record the root value, so each repeated shape is reported once. Every key is as long as its subtree, so on a chain the time and space are O of N squared. The trap I avoid is leaving out the hash mark for a missing child, which makes a left child and a right child look the same.

Big-O Invariant Derivation

Complexity & Mathematical Proof

TIME COMPLEXITY

O(N^2)

Look at the code: key_of is called once for each node and once for each missing child, so there are at most 2 * N + 1 calls. Building key copies the two child keys, and a key is as long as its subtree, so a node with s nodes in its subtree costs O(s). Reading key to update seen costs O(s) too. The sizes of all subtrees add up to at most N * (N + 1) / 2, which happens on a chain, so the total is O(N^2). On a balanced tree the sizes add up to O(N log N).

SPACE COMPLEXITY

O(N^2)

seen stores one key for each different shape. The longest keys are as long as the whole tree, so on a chain the keys add up to O(N^2) characters. The recursion goes one level deeper for each level of the tree: O(H) frames. repeated holds at most N values.

Formal Recurrence Relation

T(N)=∑vO(size(v))≤N(N+1)2⋅O(1)=O(N2)T(N) = \sum_{v} O(\text{size}(v)) \le \frac{N(N+1)}{2} \cdot O(1) = O(N^2)T(N)=∑v​O(size(v))≤2N(N+1)​⋅O(1)=O(N2)

Derivation Progression

Calls

at most 2N + 1

One call for each node and one call for each missing child.

Work per node

O(size(v))

Joining the value with the two child keys copies the whole key, and reading it for seen costs the same.

Total

O(N^2)

The subtree sizes add up to N(N+1)/2 on a chain, and to O(N log N) on a balanced tree.

Variable Definitions

NNN

Number of nodes in the tree

size(v)size(v)size(v)

Number of nodes in the subtree of node v, which is also the length of its key up to the length of one value

HHH

Height of the tree: the recursion never goes deeper

Memory Architecture & Bounds

🟣 Call Stack

O(H): one frame for each level of the path from the root to the current node

🔵 Auxiliary Heap

O(N^2): seen stores a key for each different shape, and the keys add up to O(N^2) characters on a chain

🟢 Output Space

O(N): repeated holds at most N values

Boundary Best / Worst Cases

Best Case

O(Nlog⁡N)O(N \log N)O(NlogN) on a balanced tree: the subtree sizes add up to Nlog⁡NN \log NNlogN.

Average Case

Between O(Nlog⁡N)O(N \log N)O(NlogN) and O(N2)O(N^2)O(N2): the cost is the sum of the subtree sizes, which grows with the height of the tree.

Worst Case

O(N2)O(N^2)O(N2) time and space on a chain, where the subtree sizes are N,N−1,…,1N, N-1, \dots, 1N,N−1,…,1.

Graph & Tree Traversal Frontier

Graph & Tree Traversal Frontier
Synthesizing vector architecture diagram...
Staff+ Engineering Perspective

Senior SWE Deconstruction & Hardware Caveats

ARCHITECTURAL SIGNALS & INTERVIEW TRIGGERS

Triggers: "duplicate subtrees", "the same structure with the same node values". Subtrees of one tree compared with each other: Tree as a String, where every subtree gets a key that is equal for equal subtrees.

CONSTRAINTS & BOUNDS

1≤N≤50001 \le N \le 50001≤N≤5000 nodes and values in [−200,200][-200, 200][−200,200]. Comparing every pair of subtrees node by node is up to N2/2N^2 / 2N2/2 pairs of O(N)O(N)O(N) work each. One bottom-up pass does O(N)O(N)O(N) calls, and each key is as long as its subtree, so the keys add up to O(N2)O(N^2)O(N2) characters on a chain.

FAANG PRODUCTION TRAPS & EDGE CASES

A recursive walk on a chain of 5000 nodes is 5000 calls deep, past CPython's default recursion limit of 1000: raise the limit or use an explicit stack. Every key keeps a # for a missing child and a comma between the parts. Without them, 1,2 stands for both a left child and a right child, and 111### stands for both 1 over 11 and 11 over 1.

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