Part 11•Chapter 4 of 9•Advanced
Trees, BSTs, Heaps & Tries (100 Problems)
100 problems covering tree traversals, LCA, subtree sums, BST balancing, priority queues, and trie prefix matches.
~38 min read
7,476 words
7 Sections
Reviewed & Verified (2024 Syllabus)
100 Solved ProblemsLowest Common Ancestor (LCA)Median from Data Stream
Hierarchical data structures model relational taxonomies, priority scheduling, string prefix lookups, and range query partitions. This volume curates 100 signature problems across binary tree traversals, BST invariants, heap orderings, trie bit manipulations, and advanced structural decompositions with optimal asymptotic performance.
1. Executive Summary & Learning Objectives
#This problem bank codifies 100 core challenges spanning trees, binary search trees, priority heaps, prefix tries, and multiway search structures.
By completing this problem set, you will be able to:
- Master Tree Recursive & Iterative Traversals: Formulate preorder, inorder, postorder, and level-order traversals to calculate subtree heights, diameters, and paths in time.
- Preserve Binary Search Tree Invariants: Execute validation, range deletion, rebalancing, and successor retrieval in time.
- Exploit Priority Heap Ordering: Maintain streaming medians and -th extreme elements using dual min/max heap configurations in insertion time.
- Implement String & Bitwise Tries: Construct prefix retrieval engines and 0-1 bitwise trees to answer Maximum XOR queries in bit operations.
- Apply Advanced Structural Decompositions: Implement Segment Trees, Fenwick Trees, Cartesian Trees, and Kd-Trees for multi-dimensional spatial queries.
2. Problem Taxonomy & Architecture Guide
#| Section | Problem Range | Primary Patterns Covered | Target Complexity Range |
|---|---|---|---|
| Section 1 | Q241 – Q265 | Binary Tree Fundamentals, Paths & Traversals | Time, Stack Space |
| Section 2 | Q266 – Q285 | Binary Search Tree (BST) Properties & Rebalancing | Time, to Space |
| Section 3 | Q286 – Q305 | Priority Queues, Dual Heaps & Order Statistics | Time, Space |
| Section 4 | Q306 – Q325 | Prefix Tries, Aho-Corasick & 0-1 Bitwise Tries | Time, Space |
| Section 5 | Q326 – Q340 | Segment Trees, Fenwick Trees & Tree Decompositions | to Time, Space |
Section 1: Binary Tree Fundamentals & Traversals (Q241 – Q265)
#Q241: Maximum Depth of Binary Tree
- Difficulty:
[Easy]| Pattern:[Postorder Tree Height] - Statement: Find maximum depth (number of nodes along longest path from root to leaf).
- Optimal Approach: Bottom-up DFS:
1 + max(maxDepth(root.left), maxDepth(root.right)). - Complexity: Time: | Space:
- Edge Cases: Empty tree (depth 0), single-node tree (depth 1).
Q242: Minimum Depth of Binary Tree
- Difficulty:
[Easy]| Pattern:[BFS Level Order / Leaf Check] - Statement: Find minimum depth to any leaf node.
- Optimal Approach: BFS level by level. Return depth immediately when first node with
left == NULL && right == NULLis dequeued. - Complexity: Time: | Space:
- Edge Cases: Degenerate tree (skewed line): must not treat null side as depth 0.
Q243: Invert Binary Tree
- Difficulty:
[Easy]| Pattern:[Postorder Child Swap] - Statement: Invert a binary tree (swap left and right child of every node).
- Optimal Approach: Recursively invert left and right subtrees, then swap
root.leftwithroot.right. - Complexity: Time: | Space:
- Edge Cases: Empty tree.
Q244: Same Tree
- Difficulty:
[Easy]| Pattern:[Dual Tree DFS Preorder] - Statement: Check if two binary trees are structurally identical and have identical values.
- Optimal Approach: If both null, return
true. If one null or values differ, returnfalse. Recurse left and right. - Complexity: Time: | Space:
- Edge Cases: One tree empty and the other non-empty.
Q245: Symmetric Tree
- Difficulty:
[Easy]| Pattern:[Mirror Dual Tree DFS] - Statement: Check whether a binary tree is a mirror image of itself.
- Optimal Approach: Helper
isMirror(t1, t2). Verifyt1.val == t2.val, then recurseisMirror(t1.left, t2.right)andisMirror(t1.right, t2.left). - Complexity: Time: | Space:
- Edge Cases: Single node (symmetric).
Q246: Diameter of Binary Tree
- Difficulty:
[Easy]| Pattern:[Postorder Subtree Heights] - Statement: Find length of longest path between any two nodes in a tree (path may or may not pass through root).
- Optimal Approach: At each node, diameter passing through node is
leftHeight + rightHeight. Update global max diameter, return1 + max(leftHeight, rightHeight). - Complexity: Time: | Space:
- Edge Cases: Diameter entirely contained within one subtree.
Q247: Balanced Binary Tree
- Difficulty:
[Easy]| Pattern:[Bottom-Up Height Checking] - Statement: Determine if tree is height-balanced (height of subtrees of every node differs by ).
- Optimal Approach: Postorder traversal returning height. If or any subtree returns (unbalanced), return .
- Complexity: Time: | Space:
- Edge Cases: Single node, linked-list-like degenerate tree.
Q248: Path Sum
- Difficulty:
[Easy]| Pattern:[Top-Down DFS Target Subtraction] - Statement: Return
trueif root-to-leaf path exists summing totargetSum. - Optimal Approach: Subtract
root.valfrom target. At leaf (left == NULL && right == NULL), returntarget == 0. - Complexity: Time: | Space:
- Edge Cases: Target sum zero, negative node values.
Q249: Path Sum II
- Difficulty:
[Medium]| Pattern:[Backtracking Path DFS] - Statement: Return all root-to-leaf paths that sum to
targetSum. - Optimal Approach: DFS maintaining current path. Append
root.val, recurse. At valid leaf, clone path into results. Backtrack (pop last node). - Complexity: Time: | Space:
- Edge Cases: Multiple valid paths, negative values.
Q250: Path Sum III
- Difficulty:
[Medium]| Pattern:[Prefix Sum Hash Map on Trees] - Statement: Count paths summing to
targetSum(paths do not need to start at root or end at leaf). - Optimal Approach: Hash map stores
{prefixSum: count}. At each node, addmap[currentSum - targetSum]to answer. Backtrack (decrementmap[currentSum]) on return. - Complexity: Time: | Space:
- Edge Cases: Large sum causing 32-bit integer overflow (use 64-bit int).
Q251: Binary Tree Maximum Path Sum
- Difficulty:
[Hard]| Pattern:[Postorder Max Gain] - Statement: Find maximum path sum between any two nodes in a binary tree.
- Optimal Approach: Helper returns max gain node can contribute to parent:
node.val + max(0, max(leftGain, rightGain)). Global max updated withnode.val + max(0, leftGain) + max(0, rightGain). - Complexity: Time: | Space:
- Edge Cases: All negative node values (returns maximum single node value).
Q252: Lowest Common Ancestor of a Binary Tree
- Difficulty:
[Medium]| Pattern:[Postorder Subtree LCA] - Statement: Find Lowest Common Ancestor (LCA) of nodes and .
- Optimal Approach: If
root == NULL || root == p || root == q, returnroot. Recurse left and right. If both return non-null,rootis LCA; else return non-null child. - Complexity: Time: | Space:
- Edge Cases: is ancestor of (returns ).
Q253: Lowest Common Ancestor of Deepest Leaves
- Difficulty:
[Medium]| Pattern:[Postorder Depth Matching] - Statement: Find LCA of all deepest leaves in the tree.
- Optimal Approach: Postorder returning
(depth, lcaNode). IfleftDepth == rightDepth, current node is LCA; else return result of deeper subtree. - Complexity: Time: | Space:
- Edge Cases: Only one deepest leaf (returns that leaf).
Q254: Binary Tree Level Order Traversal
- Difficulty:
[Medium]| Pattern:[Queue BFS Level Batching] - Statement: Return level-by-level node values left to right.
- Optimal Approach: Queue initialized with root. In loop, get
levelSize = queue.size(). DequeuelevelSizenodes into list, enqueue children. - Complexity: Time: | Space:
- Edge Cases: Empty tree.
Q255: Binary Tree Zigzag Level Order Traversal
- Difficulty:
[Medium]| Pattern:[BFS + Direction Toggle] - Statement: Level order traversal alternating left-to-right and right-to-left.
- Optimal Approach: Standard BFS with boolean
leftToRight. Populate each level array using direct index placement based on flag. - Complexity: Time: | Space:
- Edge Cases: Single level tree.
Q256: Binary Tree Right Side View
- Difficulty:
[Medium]| Pattern:[BFS Last in Level / Preorder Right-First] - Statement: Return values of nodes visible when looking at tree from the right side.
- Optimal Approach: Reverse preorder traversal (
Root -> Right -> Left) tracking depth. Whendepth == result.size(), appendroot.val. - Complexity: Time: | Space:
- Edge Cases: Left subtree deeper than right subtree.
Q257: Vertical Order Traversal of a Binary Tree
- Difficulty:
[Hard]| Pattern:[Coordinate BFS + Multi-key Sorting] - Statement: Traverse tree by column, sorting by
(col, row, value). - Optimal Approach: BFS recording tuples
(col, row, value). Group by column into sorted map, sort each column by row then value. - Complexity: Time: | Space:
- Edge Cases: Overlapping nodes at identical
(col, row).
Q258: Boundary of Binary Tree
- Difficulty:
[Medium]| Pattern:[Three-Stage Perimeter DFS] - Statement: Return anti-clockwise boundary nodes: left boundary, all leaves, right boundary in reverse.
- Optimal Approach: Collect root. Traverse left boundary top-down excluding leaves. DFS to collect all leaves. Traverse right boundary bottom-up.
- Complexity: Time: | Space:
- Edge Cases: Tree with no left child or no right child.
Q259: All Nodes Distance K in Binary Tree
- Difficulty:
[Medium]| Pattern:[Tree to Graph + BFS] - Statement: Return all nodes at distance from
targetnode. - Optimal Approach: DFS to populate
parentmap for every node. Run BFS outward fromtargettraversing left, right, and parent pointers up to distance . - Complexity: Time: | Space:
- Edge Cases: (returns
[target.val]), .
Q260: Construct Binary Tree from Preorder and Inorder Traversal
- Difficulty:
[Medium]| Pattern:[Recursive Range Splitting + Hash Map] - Statement: Reconstruct binary tree given preorder and inorder traversals.
- Optimal Approach: First element in preorder is root. Find root in inorder using hash map. Left of root in inorder is left subtree; right is right subtree.
- Complexity: Time: | Space:
- Edge Cases: Single node tree.
Q261: Construct Binary Tree from Inorder and Postorder Traversal
- Difficulty:
[Medium]| Pattern:[Recursive Range Splitting from End] - Statement: Reconstruct binary tree given inorder and postorder traversals.
- Optimal Approach: Last element in postorder is root. Locate root in inorder map. Recurse right subtree first, then left subtree.
- Complexity: Time: | Space:
- Edge Cases: Degenerate single-branch tree.
Q262: Serialize and Deserialize Binary Tree
- Difficulty:
[Hard]| Pattern:[Preorder BFS Sentinel String] - Statement: Design algorithm to serialize binary tree to string and deserialize back.
- Optimal Approach: BFS or Preorder DFS with
"#"or"null"for null pointers and comma delimiters. Deserializer reads tokens recursively. - Complexity: Time: | Space:
- Edge Cases: Empty tree serialized as
"#"or"".
Q263: Flatten Binary Tree to Linked List
- Difficulty:
[Medium]| Pattern:[Morris Predecessor Splicing] - Statement: Flatten tree into pre-order "linked list" using
rightpointers in-place with space. - Optimal Approach: While
curr != NULL: ifcurr.left != NULL, find rightmost node of left subtree (pred), attachcurr.righttopred.right, movecurr.lefttocurr.right, setcurr.left = NULL. Advancecurr = curr.right. - Complexity: Time: | Space:
- Edge Cases: Tree already flat.
Q264: Populating Next Right Pointers in Each Node
- Difficulty:
[Medium]| Pattern:[Level-by-Level Pointer Wiring in O(1) Space] - Statement: Populate
nextpointer of each node to its right neighbor for perfect binary tree in space. - Optimal Approach: Traverse level while wiring level :
curr.left.next = curr.right, andcurr.right.next = curr.next.left(ifcurr.nextexists). - Complexity: Time: | Space:
- Edge Cases: Single node tree.
Q265: Morris Inorder Traversal
- Difficulty:
[Medium]| Pattern:[Threaded Binary Tree Simulation] - Statement: Perform Inorder Traversal in time and strictly auxiliary space.
- Optimal Approach: Find inorder predecessor
pred. Ifpred.right == NULL, create threadpred.right = currand movecurr = curr.left. Else sever thread, printcurr.val, movecurr = curr.right. - Complexity: Time: | Space:
- Edge Cases: Tree with no left subtrees (standard right traversal).
Section 2: Binary Search Trees & Self-Balancing Trees (Q266 – Q290)
#Q266: Validate Binary Search Tree
- Difficulty:
[Medium]| Pattern:[Range Invariant DFS] - Statement: Return
trueif binary tree satisfies strict BST property. - Optimal Approach: Helper
validate(node, minVal, maxVal). Ensure . Recurse left with upper bound , right with lower bound . - Complexity: Time: | Space:
- Edge Cases: Node values equal to
INT_MINorINT_MAX(use 64-bit int or null-box wrappers for bounds).
Q267: Lowest Common Ancestor of a Binary Search Tree
- Difficulty:
[Medium]| Pattern:[BST Search Divergence] - Statement: Find LCA of and in a BST in time.
- Optimal Approach: Start at root. If both and are smaller, move left. If both are larger, move right. The first node where and diverge is their LCA!
- Complexity: Time: | Space: iterative
- Edge Cases: One node is the root itself.
Q268: Kth Smallest Element in a BST
- Difficulty:
[Medium]| Pattern:[Iterative Inorder Traversal] - Statement: Find -th smallest element in a BST.
- Optimal Approach: Iterative Inorder traversal using stack. Decrement on each popped node; when , return popped node's value.
- Complexity: Time: | Space:
- Edge Cases: (leftmost node), (rightmost node).
Q269: Convert Sorted Array to Binary Search Tree
- Difficulty:
[Easy]| Pattern:[Divide and Conquer Midpoint] - Statement: Convert sorted ascending array into height-balanced BST.
- Optimal Approach: Choose
mid = (L + R) / 2as root. Recursively construct left subtree from and right from . - Complexity: Time: | Space:
- Edge Cases: Even number of elements (choice of left or right mid valid).
Q270: Convert Sorted List to Binary Search Tree
- Difficulty:
[Medium]| Pattern:[Inorder Simulation with List Pointer] - Statement: Convert sorted linked list to balanced BST in time and space.
- Optimal Approach: Count length . Recursively build left subtree of size , assign current list node to root, advance list pointer, build right subtree.
- Complexity: Time: | Space:
- Edge Cases: Single-node list.
Q271: Delete Node in a BST
- Difficulty:
[Medium]| Pattern:[Three-Case BST Deletion] - Statement: Delete node with given key in BST.
- Optimal Approach: If key smaller, recurse left; if larger, recurse right. If key found: 0 children return null; 1 child return child; 2 children replace value with Inorder Successor, delete successor from right subtree.
- Complexity: Time: | Space:
- Edge Cases: Deleting root node, deleting node with 2 children.
Q272: Insert into a Binary Search Tree
- Difficulty:
[Medium]| Pattern:[BST Search Placement] - Statement: Insert value into BST preserving order.
- Optimal Approach: Traverse down: if , go left (if null, attach new node); else go right.
- Complexity: Time: | Space: iterative
- Edge Cases: Inserting into empty tree (new node is root).
Q273: Inorder Successor in BST
- Difficulty:
[Medium]| Pattern:[BST Search with Candidate Tracking] - Statement: Find inorder successor of node in BST.
- Optimal Approach: If has right child, successor is leftmost node in right subtree. Else traverse from root: if ,
successor = curr, go left; else go right. - Complexity: Time: | Space:
- Edge Cases: is maximum element (successor is
NULL).
Q274: Inorder Predecessor in BST
- Difficulty:
[Medium]| Pattern:[BST Search with Candidate Tracking] - Statement: Find inorder predecessor of node in BST.
- Optimal Approach: If has left child, predecessor is rightmost node in left subtree. Else traverse from root: if ,
pred = curr, go right; else go left. - Complexity: Time: | Space:
- Edge Cases: is minimum element (predecessor is
NULL).
Q275: Binary Search Tree Iterator
- Difficulty:
[Medium]| Pattern:[Controlled Stack Inorder] - Statement: Implement iterator over BST with average
next()and memory. - Optimal Approach: Stack storing ancestors. In constructor, push all left children from root. On
next(), pop node, push all left children of popped node's right child. - Complexity: Time: amortized | Space:
- Edge Cases: Tree with only right children.
Q276: Two Sum IV - Input is a BST
- Difficulty:
[Easy]| Pattern:[Dual BST Iterators (Two Pointers)] - Statement: Check if two nodes in BST sum to
target. - Optimal Approach: Run two BST iterators: one forward (smallest to largest) and one backward (largest to smallest). Apply two pointers on iterator outputs!
- Complexity: Time: | Space:
- Edge Cases: Target sum requires using same node twice (prevented by iterator equality check).
Q277: Trim a Binary Search Tree
- Difficulty:
[Medium]| Pattern:[Recursive Pruning] - Statement: Trim BST so all elements lie in .
- Optimal Approach: If
root.val < low, entire left subtree is invalid; returntrim(root.right). Ifroot.val > high, returntrim(root.left). Else trim both subtrees. - Complexity: Time: | Space:
- Edge Cases: All nodes trimmed out (returns
NULL).
Q278: Recover Binary Search Tree
- Difficulty:
[Medium]| Pattern:[Morris Inorder Inversion Detection] - Statement: Exactly two nodes in a BST were swapped by mistake. Recover tree in auxiliary space.
- Optimal Approach: Morris Inorder traversal tracking
prev. First violation: . Second violation: . Swap values of and . - Complexity: Time: | Space:
- Edge Cases: The two swapped nodes are adjacent in inorder traversal.
Q279: Unique Binary Search Trees
- Difficulty:
[Medium]| Pattern:[Catalan Numbers DP] - Statement: Count structurally unique BSTs storing values .
- Optimal Approach: (Catalan number ).
- Complexity: Time: | Space:
- Edge Cases: (result 1).
Q280: Balance a Binary Search Tree
- Difficulty:
[Medium]| Pattern:[Inorder Extraction + Midpoint Rebuild] - Statement: Convert unbalanced BST into balanced BST.
- Optimal Approach: Inorder traversal to extract sorted array of values. Recursively construct balanced BST from array using midpoint.
- Complexity: Time: | Space:
- Edge Cases: Completely degenerate linear tree.
Q281: Maximum Sum BST in Binary Tree
- Difficulty:
[Hard]| Pattern:[Postorder Subtree Validation Tuple] - Statement: Find maximum sum of all keys of any subtree that is also a valid BST.
- Optimal Approach: Postorder helper returns
(isBST, minVal, maxVal, sum). Current tree is BST iff left and right are BSTs and . - Complexity: Time: | Space:
- Edge Cases: All negative node values (empty tree is valid BST with sum 0).
Q282: Count Complete Tree Nodes
- Difficulty:
[Medium]| Pattern:[Binary Search on Complete Tree Heights] - Statement: Count nodes in complete binary tree in strictly less than time.
- Optimal Approach: Compute left depth and right depth . If , tree is perfect: return . Else return .
- Complexity: Time: | Space:
- Edge Cases: Single node tree.
Q283: Range Sum of BST
- Difficulty:
[Easy]| Pattern:[BST Pruning DFS] - Statement: Return sum of values of all nodes with value in .
- Optimal Approach: If , search only right. If , search only left. If inside range, add and search both sides.
- Complexity: Time: where is nodes in range | Space:
- Edge Cases: No nodes in range.
Q284: Construct BST from Preorder Traversal
- Difficulty:
[Medium]| Pattern:[Upper Bound Recursive DFS] - Statement: Construct BST given its preorder traversal.
- Optimal Approach: Maintain index and upper bound . If current element exceeds , return null. Recurse left with bound , right with .
- Complexity: Time: | Space:
- Edge Cases: Monotonically decreasing preorder (skewed left tree).
Q285: Check if Array Can Represent Preorder Traversal of BST
- Difficulty:
[Medium]| Pattern:[Monotonic Stack Lower Bound Tracking] - Statement: Check if array is valid preorder traversal of a BST in time and space.
- Optimal Approach: Monotonic decreasing stack. Maintain . If incoming element , invalid. While stack top , pop and update .
- Complexity: Time: | Space:
- Edge Cases: Strictly decreasing array (valid).
Q286: All Elements in Two Binary Search Trees
- Difficulty:
[Medium]| Pattern:[Dual Inorder Iterators Merge] - Statement: Return sorted list containing all integers from two BSTs.
- Optimal Approach: Two iterative Inorder stacks. At each step, compare top elements of both stacks, pop the smaller, append to result.
- Complexity: Time: | Space:
- Edge Cases: One tree empty.
Q287: Closest Binary Search Tree Value
- Difficulty:
[Easy]| Pattern:[BST Search Binary Walk] - Statement: Find value in BST that is closest to target.
- Optimal Approach: Maintain
closest. In loop: if , updateclosest. If , go left; else go right. - Complexity: Time: | Space:
- Edge Cases: Target equidistant from two nodes (choose smaller per spec).
Q288: Unique Binary Search Trees II
- Difficulty:
[Medium]| Pattern:[Divide and Conquer BST Generation] - Statement: Generate all structurally unique BSTs storing values .
- Optimal Approach: Helper
generate(start, end). Pick each as root. Generate all left subtrees from[start, i-1]and right subtrees from[i+1, end]. Cross-product combinations. - Complexity: Time: | Space:
- Edge Cases: .
Q289: Red-Black Tree Verification
- Difficulty:
[Hard]| Pattern:[Black-Height & Double-Red Verification] - Statement: Given binary tree with node colors, verify if all 5 RBT invariants hold.
- Optimal Approach: 1. Root must be Black. 2. DFS returns black-height; if red node has red child, fail. If black-heights of subtrees differ, fail.
- Complexity: Time: | Space:
- Edge Cases: Empty tree (valid).
Q290: Convert BST to Greater Tree
- Difficulty:
[Medium]| Pattern:[Reverse Inorder Accumulator] - Statement: Convert BST such that every key is updated to original key plus sum of all greater keys.
- Optimal Approach: Reverse Inorder traversal (
Right -> Root -> Left). Maintain running sum, setnode.val += runningSum, updaterunningSum = node.val. - Complexity: Time: | Space:
- Edge Cases: Single node tree.
Section 3: Heaps & Priority Queues (Q291 – Q315)
#Q291: Kth Largest Element in an Array
- Difficulty:
[Medium]| Pattern:[Min-Heap of Size K / QuickSelect] - Statement: Find -th largest element in unsorted array.
- Optimal Approach: Maintain min-heap of size . Push each element; if size , pop. Top of heap is -th largest. (Alternatively QuickSelect in average).
- Complexity: Time: | Space:
- Edge Cases: Duplicate values, .
Q292: Top K Frequent Elements
- Difficulty:
[Medium]| Pattern:[Bucket Sort / Min-Heap] - Statement: Return most frequent elements.
- Optimal Approach: Count frequencies into map. Create array of buckets where
bucket[freq]stores list of elements with that frequency. Scan from high to low frequency. - Complexity: Time: | Space:
- Edge Cases: All elements have unique frequency 1.
Q293: Find Median from Data Stream
- Difficulty:
[Hard]| Pattern:[Dual Heaps (Max-Heap & Min-Heap)] - Statement: Design data structure supporting adding numbers and finding running median in .
- Optimal Approach:
leftMaxHeap(stores smaller half) andrightMinHeap(stores larger half). Balance heaps so sizes differ by at most 1. - Complexity: Add: | Find Median: | Space:
- Edge Cases: Even vs odd total numbers.
Q294: Sliding Window Median
- Difficulty:
[Hard]| Pattern:[Dual Heaps with Lazy Deletion] - Statement: Return median of every sliding window of size .
- Optimal Approach: Dual heaps maintaining smaller and larger halves. Use hash map for lazy removal of outgoing elements when popped.
- Complexity: Time: | Space:
- Edge Cases: .
Q295: Merge K Sorted Lists
- Difficulty:
[Hard]| Pattern:[Min-Heap K Pointers] - Statement: Merge sorted lists into one sorted list.
- Optimal Approach: Push heads into min-heap. Extract min node, advance its pointer and push to heap.
- Complexity: Time: | Space:
- Edge Cases: Lists containing empty heads, .
Q296: Find K Pairs with Smallest Sums
- Difficulty:
[Medium]| Pattern:[Min-Heap Multi-Index Walk] - Statement: Given two sorted arrays, find pairs with smallest sums.
- Optimal Approach: Push for all into min-heap. Extract min , push next pair .
- Complexity: Time: | Space:
- Edge Cases: .
Q297: Task Scheduler
- Difficulty:
[Medium]| Pattern:[Max Frequency Math / Max-Heap] - Statement: Execute tasks with cooling interval minimizing total intervals.
- Optimal Approach: Find max task frequency and count of tasks with frequency (). Answer is .
- Complexity: Time: | Space:
- Edge Cases: (no cooling).
Q298: Minimum Cost to Connect Sticks / Huffman Coding
- Difficulty:
[Medium]| Pattern:[Min-Heap Greedy Pairing] - Statement: Connect sticks into one stick; cost to connect two sticks is their sum. Minimize cost.
- Optimal Approach: Min-heap of stick lengths. Extract two smallest sticks, add their sum to total cost, push sum back to heap until 1 stick remains.
- Complexity: Time: | Space:
- Edge Cases: Array with 1 stick (cost 0).
Q299: Furthest Building You Can Reach
- Difficulty:
[Medium]| Pattern:[Min-Heap for Ladders] - Statement: Climb buildings using bricks and ladders. Maximize distance reached.
- Optimal Approach: Use min-heap of size to track largest height climbs. For smaller climbs, spend bricks. If bricks exhausted, return current building.
- Complexity: Time: | Space:
- Edge Cases: 0 ladders, bricks suffice for all buildings.
Q300: Seat Reservation Manager
- Difficulty:
[Medium]| Pattern:[Min-Heap Available Seats] - Statement: Manage reservation of smallest unreserved seat numbers.
- Optimal Approach: Min-heap initialized with .
reserve()pops min,unreserve(seat)pushes seat back. - Complexity: Time: all ops | Space:
- Edge Cases: Unreserving a seat that becomes the new minimum.
Q301: Process Tasks Using Servers
- Difficulty:
[Medium]| Pattern:[Dual Heaps (Free & Busy Servers)] - Statement: Assign tasks to available servers with smallest weight (breaking ties by index).
- Optimal Approach:
freeServersmin-heap by(weight, index).busyServersmin-heap by(freeTime, weight, index). Advance time and transfer servers. - Complexity: Time: | Space:
- Edge Cases: No servers available when task arrives (jump time forward).
Q302: Single-Threaded CPU
- Difficulty:
[Medium]| Pattern:[Min-Heap Shortest Job First] - Statement: Execute tasks ordered by arrival time, choosing shortest processing time when available.
- Optimal Approach: Sort tasks by enqueue time. Min-heap of available tasks by
(processingTime, index). Maintain current time. - Complexity: Time: | Space:
- Edge Cases: CPU idle between task arrivals.
Q303: IPO (Maximize Capital)
- Difficulty:
[Hard]| Pattern:[Dual Heaps Capital vs Profit] - Statement: Pick at most projects to maximize final capital starting with .
- Optimal Approach: Min-heap of projects by
capitalRequirement. Max-heap of affordable projects byprofit. At each step, push all newly affordable projects to max-heap and execute best. - Complexity: Time: | Space:
- Edge Cases: Cannot afford any project initially.
Q304: Maximum Performance of a Team
- Difficulty:
[Hard]| Pattern:[Sort by Efficiency + Min-Heap Speed] - Statement: Choose at most engineers to maximize .
- Optimal Approach: Sort engineers by efficiency descending. Maintain min-heap of speeds of size . As each engineer is added (acting as minimum efficiency), update max performance.
- Complexity: Time: | Space:
- Edge Cases: .
Q305: Minimum Number of Refueling Stops
- Difficulty:
[Hard]| Pattern:[Max-Heap Greedy Fuel] - Statement: Reach destination with initial fuel, refueling at stations on the way.
- Optimal Approach: Max-heap of fuel at passed gas stations. When fuel reaches 0 before next station, pop max fuel station and refuel.
- Complexity: Time: | Space:
- Edge Cases: Cannot reach next station even after using all passed stations.
Q306: Swim in Rising Water
- Difficulty:
[Hard]| Pattern:[Dijkstra Min-Heap] - Statement: Find minimum time to swim from to in grid where water rises.
- Optimal Approach: Min-heap of tuples
(maxElevationSoFar, r, c). Expand 4-directional neighbors, pushing . - Complexity: Time: | Space:
- Edge Cases: .
Q307: Path with Maximum Minimum Value
- Difficulty:
[Medium]| Pattern:[Max-Heap Dijkstra / Modified BFS] - Statement: Find path from start to end maximizing the minimum cell score along path.
- Optimal Approach: Max-heap of
(minScoreOnPath, r, c). Greedily explore largest neighbor cell first. - Complexity: Time: | Space:
- Edge Cases: Grid with 1 cell.
Q308: Reduce Array Size to The Half
- Difficulty:
[Medium]| Pattern:[Max-Heap Greedy Frequencies] - Statement: Choose minimum set of integers to remove at least half the elements.
- Optimal Approach: Max-heap of frequencies. Greedily pop largest frequencies until total removed .
- Complexity: Time: | Space:
- Edge Cases: All elements identical (returns 1).
Q309: Last Stone Weight
- Difficulty:
[Easy]| Pattern:[Max-Heap Simulation] - Statement: Smash two heaviest stones: if equal, destroy both; else push difference.
- Optimal Approach: Max-heap. Pop top two elements, push difference if until stone remains.
- Complexity: Time: | Space:
- Edge Cases: All stones destroy each other (returns 0).
Q310: Relative Ranks
- Difficulty:
[Easy]| Pattern:[Max-Heap with Indices] - Statement: Assign medals (Gold, Silver, Bronze, 4, 5...) based on scores.
- Optimal Approach: Max-heap storing
(score, originalIndex). Pop assigning rank labels. - Complexity: Time: | Space:
- Edge Cases: Array length .
Q311: Take Gifts From the Richest Pile
- Difficulty:
[Easy]| Pattern:[Max-Heap Simulation] - Statement: For seconds, pick largest pile and replace with .
- Optimal Approach: Max-heap. Pop max, push , repeat times. Sum heap elements.
- Complexity: Time: | Space:
- Edge Cases: Piles reduced to 1.
Q312: Maximum Subsequence Score
- Difficulty:
[Medium]| Pattern:[Sort + Min-Heap] - Statement: Maximize of size .
- Optimal Approach: Sort pairs by descending. Min-heap of size for . Update score with .
- Complexity: Time: | Space:
- Edge Cases: .
Q313: Kth Largest Element in a Stream
- Difficulty:
[Easy]| Pattern:[Min-Heap of Size K] - Statement: Design class to find -th largest element in dynamic stream.
- Optimal Approach: Min-heap of size .
add(val)pushes to heap and pops if size . Return heap top. - Complexity: Add: | Space:
- Edge Cases: Initial array has elements.
Q314: Minimum Operations to Halve Array Sum
- Difficulty:
[Medium]| Pattern:[Max-Heap Greedy Reduction] - Statement: Halve array sum by picking largest element and dividing by 2 repeatedly.
- Optimal Approach: Max-heap of doubles. Pop largest, subtract half from current sum, push half back until total reduced by .
- Complexity: Time: | Space:
- Edge Cases: Precision handling with floating points.
Q315: Find K-th Smallest Pair Distance
- Difficulty:
[Hard]| Pattern:[Binary Search on Answer + Sliding Window] - Statement: Find -th smallest distance among all pairs in array.
- Optimal Approach: Sort array. Binary search distance . Count pairs with distance using two pointers sliding window.
- Complexity: Time: | Space:
- Edge Cases: Many duplicate distances.
Section 4: Tries, Advanced Trees & Range Structures (Q316 – Q340)
#Q316: Implement Trie (Prefix Tree)
- Difficulty:
[Medium]| Pattern:[Standard Alphabet Trie] - Statement: Implement
insert(word),search(word), andstartsWith(prefix). - Optimal Approach: Node with array of 26 child pointers and
isEndboolean. Walk character pointers. - Complexity: Time: all ops | Space:
- Edge Cases: Empty word
"".
Q317: Design Add and Search Words Data Structure
- Difficulty:
[Medium]| Pattern:[Trie Backtracking with Wildcard] - Statement: Support searching words with wildcard character
.matching any letter. - Optimal Approach: Trie structure. For
., branch recursively into all 26 non-null children; for letters, step into single child. - Complexity: Search: normal, worst case with many
.| Space: - Edge Cases: Words composed entirely of
....
Q318: Word Search II
- Difficulty:
[Hard]| Pattern:[Trie + 2D Grid Backtracking] - Statement: Find all words from dictionary present on Boggle board.
- Optimal Approach: Build Trie from words. Run DFS on grid cells simultaneously walking down the Trie. Prune leaf Trie nodes when word is matched to optimize future searches!
- Complexity: Time: | Space:
- Edge Cases: Duplicate words on board (prevented by clearing
isEndor storing word in leaf).
Q319: Maximum XOR of Two Numbers in an Array
- Difficulty:
[Medium]| Pattern:[0-1 Bitwise Trie Greedy Search] - Statement: Find maximum result of in time.
- Optimal Approach: Insert all numbers into 0-1 Trie (MSB to LSB). For each number, greedily branch toward the opposite bit to maximize XOR.
- Complexity: Time: | Space:
- Edge Cases: Array of all identical numbers (XOR is 0).
Q320: Maximum XOR With an Element From Array
- Difficulty:
[Hard]| Pattern:[Offline Query Sorting + 0-1 Trie] - Statement: For query , maximize where .
- Optimal Approach: Sort queries by ascending. Sort array ascending. Greedily insert array elements into 0-1 Trie before processing query.
- Complexity: Time: | Space:
- Edge Cases: No array element (returns ).
Q321: Replace Words
- Difficulty:
[Medium]| Pattern:[Trie Shortest Root Match] - Statement: Replace sentence words with shortest dictionary root if matching.
- Optimal Approach: Insert roots into Trie. For each word in sentence, traverse Trie: if
isEndencountered, replace word with root; if mismatch, keep original. - Complexity: Time: | Space:
- Edge Cases: Multiple roots match word (choose shortest root).
Q322: Map Sum Pairs
- Difficulty:
[Medium]| Pattern:[Trie Prefix Score Accumulator] - Statement: Support
insert(key, val)andsum(prefix)returning sum of values of all keys starting with prefix. - Optimal Approach: Each Trie node maintains running sum of all descendant keys:
node.score += (newVal - oldVal).sum(prefix)returns score of prefix leaf in ! - Complexity: Time: all ops | Space:
- Edge Cases: Overwriting value of an existing key.
Q323: Concatenated Words
- Difficulty:
[Hard]| Pattern:[Trie + Memoized Word Break DFS] - Statement: Find all words in dictionary formed by concatenating shorter dictionary words.
- Optimal Approach: Sort words by length. Insert shorter words into Trie. For current word, check if it can be partitioned using words already in Trie.
- Complexity: Time: | Space:
- Edge Cases: Empty string, single letter words.
Q324: Palindrome Pairs
- Difficulty:
[Hard]| Pattern:[Trie of Reversed Words] - Statement: Find pairs such that forms a palindrome.
- Optimal Approach: Insert reversed words into Trie. For each word, traverse Trie checking palindromic suffixes, and check remaining Trie branches for palindromic tails.
- Complexity: Time: | Space:
- Edge Cases: Empty word
""pairing with any palindrome word.
Q325: Stream of Characters
- Difficulty:
[Hard]| Pattern:[Trie of Reversed Suffixes] - Statement: Support
query(letter)returning true if any suffix of stream matches a dictionary word. - Optimal Approach: Insert words in reverse into Trie. Maintain stream buffer. On query, scan buffer backwards from latest character into Trie.
- Complexity: Time: per query | Space:
- Edge Cases: Very long stream (cap buffer size to max word length).
Q326: Range Sum Query - Mutable
- Difficulty:
[Medium]| Pattern:[Segment Tree / Binary Indexed Tree] - Statement: Support point updates and range sum queries.
- Optimal Approach: 1D Fenwick Tree (BIT) with
i += (i & -i)for updates andi -= (i & -i)for prefix sum queries. - Complexity: Time: all ops | Space:
- Edge Cases: Update with zero delta.
Q327: Range Sum Query 2D - Mutable
- Difficulty:
[Hard]| Pattern:[2D Binary Indexed Tree] - Statement: Support point updates and 2D range sum queries in matrix.
- Optimal Approach: 2D Fenwick Tree where both dimensions use
(i & -i)bitwise navigation. - Complexity: Time: | Space:
- Edge Cases: Single cell updates and queries.
Q328: Count of Smaller Numbers After Self
- Difficulty:
[Hard]| Pattern:[Coordinate Compression + Fenwick Tree] - Statement: For each element, count elements to its right that are strictly smaller.
- Optimal Approach: Coordinate compress values to ranks . Scan array from right to left: query BIT for rank , then add 1 to BIT at rank .
- Complexity: Time: | Space:
- Edge Cases: Duplicate numbers, negative numbers.
Q329: Reverse Pairs
- Difficulty:
[Hard]| Pattern:[Fenwick Tree / Merge Sort Inversions] - Statement: Count pairs with and .
- Optimal Approach: Coordinate compress both and . Traverse right-to-left using Fenwick Tree.
- Complexity: Time: | Space:
- Edge Cases: exceeding 32-bit signed integer (overflow).
Q330: Static Range Minimum Query (RMQ)
- Difficulty:
[Medium]| Pattern:[Sparse Table strictly O(1)] - Statement: Query minimum in subarray in time after preprocessing.
- Optimal Approach: Sparse Table
ST[i][k]storing minimum in . Query overlaps two power-of-two intervals: where . - Complexity: Preprocess: | Query: | Space:
- Edge Cases: ().
Q331: Segment Tree Lazy Propagation for Range Updates
- Difficulty:
[Hard]| Pattern:[Lazy Tag Push-Down] - Statement: Support range additions and range sum queries in time.
- Optimal Approach: Maintain
lazyarray. When visiting node, push down pending lazy updates to children before recursing. - Complexity: Time: all ops | Space:
- Edge Cases: Overlapping range updates.
Q332: Falling Squares
- Difficulty:
[Hard]| Pattern:[Coordinate Compressed Segment Tree] - Statement: Squares drop on number line; stack if landing on existing square. Return max height after each drop.
- Optimal Approach: Coordinate compress -intervals . Segment tree with lazy propagation maintains maximum height over intervals.
- Complexity: Time: | Space:
- Edge Cases: Squares touching at boundaries (do not stack).
Q333: My Calendar III via Segment Tree
- Difficulty:
[Hard]| Pattern:[Dynamic / Segment Tree with Lazy Max] - Statement: Return max -booking using dynamic segment tree without pre-allocating large range.
- Optimal Approach: Dynamic pointer-based segment tree over range . Range add 1 for each interval, query root maximum.
- Complexity: Time: per booking | Space:
- Edge Cases: Large timestamps up to .
Q334: Lowest Common Ancestor via Binary Lifting
- Difficulty:
[Hard]| Pattern:[Binary Lifting Table] - Statement: Preprocess tree to answer LCA queries in time.
- Optimal Approach: Table
up[node][k]storing -th ancestor. Bring deeper node to same depth using binary jumps, then jump both nodes simultaneously until parents match. - Complexity: Preprocess: | Query: | Space:
- Edge Cases: One node is ancestor of the other.
Q335: Tree Diameter & Centroid Finding
- Difficulty:
[Medium]| Pattern:[Double DFS & Subtree Halving] - Statement: 1. Find diameter using 2 BFS/DFS passes. 2. Find centroid where each subtree .
- Optimal Approach: Run BFS from arbitrary node to find furthest node . Run BFS from to find furthest node ; distance is diameter. For centroid, DFS picking child with size .
- Complexity: Time: | Space:
- Edge Cases: Trees with 2 centroids.
Q336: Heavy-Light Decomposition Path Queries
- Difficulty:
[Hard]| Pattern:[HLD + Segment Tree] - Statement: Update nodes along path and query max along path in time.
- Optimal Approach: Heavy-Light Decomposition maps tree paths onto segment tree. Jump across light edges, query heavy paths in each.
- Complexity: Time: | Space:
- Edge Cases: and on same heavy path.
Q337: Subtree Queries via Euler Tour
- Difficulty:
[Medium]| Pattern:[Euler Tour Flattening + Segment Tree] - Statement: Update and query entire subtrees in time.
- Optimal Approach: Euler tour assigns entry and exit times . Entire subtree of corresponds to contiguous subarray ! Use Fenwick or Segment Tree.
- Complexity: Time: | Space:
- Edge Cases: Leaf node subtree (interval of size 1).
Q338: Cartesian Tree Linear Construction
- Difficulty:
[Hard]| Pattern:[Monotonic Stack RMQ Tree] - Statement: Build Cartesian Tree from array in time.
- Optimal Approach: Monotonic stack maintaining right spine. New node pops elements with value current, becomes their parent, attaches to stack top.
- Complexity: Time: | Space:
- Edge Cases: Array sorted ascending (all right children), descending (all left children).
Q339: Kd-Tree 2D Nearest Neighbor Search
- Difficulty:
[Hard]| Pattern:[Alternating Splitting Hyperplanes with Pruning] - Statement: Find closest 2D point to query point in average time.
- Optimal Approach: Kd-tree alternating and splits. Backtrack and prune subtrees where distance to splitting line best distance seen so far.
- Complexity: Time: average | Space:
- Edge Cases: Multiple points with identical distances.
Q340: Implicit Treap Dynamic Array
- Difficulty:
[Hard]| Pattern:[Implicit Key Split & Merge] - Statement: Implement array supporting arbitrary range reverse in time.
- Optimal Approach: Implicit Treap where key is subtree size.
reverse(l, r)splits target interval, toggles lazy reverse bit on root, and merges back. - Complexity: Time: all ops | Space:
- Edge Cases: Reversing range of size 1.
References & Academic Attribution
#- Skiena, S. S. (2020). The Algorithm Design Manual (3rd ed.). Springer.
- Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2022). Introduction to Algorithms (4th ed.). MIT Press.
- USA Computing Olympiad (USACO) & CP-Algorithms Archives (2024). Curated Competitive Programming and Algorithm Verification Standards.