Stage II: Hard Questions

Linked List

Pattern: Cycle Detection & Advanced Pointers

7. Linked List Cycle

Problem: Given the head of a linked list, determine if the linked list has a cycle in it.

Concept Tested: The "fast and slow pointer" (Floyd's Tortoise and Hare) algorithm.

Companies: Amazon, Microsoft, Apple, Bloomberg

8. Linked List Cycle II

Problem: Given the head of a linked list, return the node where the cycle begins. If there is no cycle, return null.

Concept Tested: An advanced application of the fast/slow pointer technique.

Companies: Microsoft, Amazon, Apple, Oracle

9. Copy List with Random Pointer

Problem: Construct a deep copy of a linked list where each node contains an additional random pointer, which could point to any node in the list or null.

Concept Tested: Using a hash map to associate original nodes with their copies to resolve the random pointers correctly.

Companies: Amazon, Microsoft, Bloomberg, Facebook (Meta)

Pattern: Complex Reversal & Data Structure Design

10. Reverse Nodes in k-Group

Problem: Given the head of a linked list, reverse the nodes of the list k at a time, and return the modified list.

Concept Tested: Advanced pointer manipulation, recursion, and breaking the problem into sub-problems.

Companies: Microsoft, Amazon, Google, Facebook (Meta)

11. LRU Cache

Problem: Design a data structure that follows the constraints of a Least Recently Used (LRU) Cache. It must support get(key) and put(key, value) operations in O(1) time.

Concept Tested: Combining a Hash Map (for O(1) access) and a Doubly Linked List (for O(1) eviction/ordering).

Companies: Amazon, Google, Facebook (Meta), Microsoft, Apple, Dropbox

Stacks

Pattern: Monotonic Stack

This advanced technique uses a stack to keep track of elements in a strictly increasing or decreasing order.

6. Largest Rectangle in Histogram

Problem: Given bar heights, find the area of the largest rectangle that can be formed.

Concept Tested: The canonical monotonic stack problem for finding previous/next smaller elements.

Companies: Amazon, Google, Microsoft, Facebook (Meta)

7. Trapping Rain Water

Problem: Given an elevation map, compute how much water it can trap.

Concept Tested: Using a stack to keep track of the boundaries of a potential water trap.

Companies: Amazon, Google, Microsoft, Apple, Bloomberg

Pattern: Expression Parsing

This pattern requires a stack to handle operator precedence and nested calculations.

8. Basic Calculator

Problem: Implement a basic calculator to evaluate a string expression with +, -, (, and ).

Concept Tested: Using a stack to handle nested parentheses and signs.

Companies: Google, Microsoft, Facebook (Meta), Amazon

Queues

Pattern: Advanced Queue & Deque Applications

These problems require a more sophisticated use of queues or a double-ended queue (deque).

5. Sliding Window Maximum

Problem: Find the maximum value in each sliding window of size k.

Concept Tested: Using a Deque to maintain a monotonically decreasing window of indices.

Companies: Amazon, Google, Facebook (Meta), Microsoft

6. Shortest Path in a Binary Matrix

Problem: Find the shortest path from top-left to bottom-right in a grid of 0s and 1s.

Concept Tested: A complex BFS on a 2D grid where the queue stores the path length.

Companies: Amazon, Facebook (Meta), Google

Pattern: Data Structure Design

7. Design Circular Queue

Problem: Design your implementation of the circular queue data structure.

Concept Tested: Implementing Circular Queue logic with an array and pointers.

Companies: Amazon, Microsoft, Apple

Hashing

Pattern: Advanced Hashing & Data Structure Synthesis

These problems require combining hash maps with other data structures or using them in more complex algorithms.

6. Subarray Sum Equals K

Problem: Return the total number of subarrays whose sum equals k.

Concept Tested: Using a hash map to store prefix sums and their frequencies.

Companies: Amazon, Facebook (Meta), Google, Microsoft

7. Longest Substring Without Repeating Characters

Problem: Find the length of the longest substring without repeating characters.

Concept Tested: Combining a hash map with the sliding window technique.

Companies: Amazon, Microsoft, Apple, Google, Facebook (Meta)

8. Insert Delete GetRandom O(1)

Problem: Implement a data structure that supports insert, remove, and getRandom all in average O(1) time.

Concept Tested: A brilliant synthesis of a hash map and a dynamic array.

Companies: Amazon, Facebook (Meta), Google, Microsoft, Twitter

Trees

Pattern: Advanced Traversal & Tree Construction

These problems require a deeper understanding of recursion, how information is passed up and down the call stack, and how different traversal orders uniquely define a tree's structure.

7. Binary Tree Maximum Path Sum

Concept Tested: An advanced DFS where the recursive helper function must do two things: return the maximum path sum that can extend upwards to its parent, and update a global maximum for paths that are contained entirely within the current subtree (i.e., paths that "turn" at the current node).

Companies: Google, Amazon, Facebook (Meta), Microsoft

View Python Solution

class Solution:
    def maxPathSum(self, root: TreeNode) -> int:
        self.max_sum = float('-inf')
    def dfs(node):
        if not node:
            return 0

        left_max = max(0, dfs(node.left))
        right_max = max(0, dfs(node.right))

        self.max_sum = max(self.max_sum, node.val + left_max + right_max)

        return node.val + max(left_max, right_max)

    dfs(root)
    return self.max_sum

8. Construct Binary Tree from Preorder and Inorder Traversal

Concept Tested: A classic problem demonstrating the unique properties of traversals. The preorder traversal always gives you the root of any subtree, while the inorder traversal tells you which nodes are in the left subtree and which are in the right subtree relative to that root.

Companies: Amazon, Microsoft, Bloomberg, Apple

View Python Solution


def buildTree(preorder: list[int], inorder: list[int]) -> TreeNode:
    if not preorder or not inorder:
        return None
root_val = preorder[0]
root = TreeNode(root_val)

mid_idx = inorder.index(root_val)

root.left = buildTree(preorder[1 : mid_idx + 1], inorder[:mid_idx])
root.right = buildTree(preorder[mid_idx + 1 :], inorder[mid_idx + 1:])

return root

9. Serialize and Deserialize Binary Tree

Concept Tested: A practical problem that requires converting a tree into a string format and vice-versa. A common approach is to use a preorder DFS for serialization (to capture the structure including null nodes) and a queue or an iterator for deserialization.

Companies: Amazon, Google, Facebook (Meta), Microsoft

View Python Solution


class Codec:
    def serialize(self, root):
        res = []
        def dfs(node):
            if not node:
                res.append("N")
                return
            res.append(str(node.val))
            dfs(node.left)
            dfs(node.right)
        dfs(root)
        return ",".join(res)
def deserialize(self, data):
    vals = data.split(',')
    self.i = 0
    def dfs():
        if vals[self.i] == "N":
            self.i += 1
            return None
        node = TreeNode(int(vals[self.i]))
        self.i += 1
        node.left = dfs()
        node.right = dfs()
        return node
    return dfs()

10. Lowest Common Ancestor of a Binary Tree

Concept Tested: A clever recursive solution. The recursive function returns the LCA if found in its subtree, or p or q if one of them is found, or null. If a node receives non-null values from both its left and right recursive calls, it must be the LCA.

Companies: Amazon, Facebook (Meta), Microsoft, Apple, LinkedIn

View Python Solution


def lowestCommonAncestor(root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
    if not root or root == p or root == q:
        return root
left = lowestCommonAncestor(root.left, p, q)
right = lowestCommonAncestor(root.right, p, q)

if left and right:
    return root

return left or right

Binary Search Tree

Pattern: BST Construction & Deletion

These problems involve the more complex operations of building a balanced BST or implementing the tricky deletion logic.

7. Convert Sorted Array to Binary Search Tree

Concept Tested: Building a height-balanced BST to avoid the O(n) worst-case scenario. This is achieved by recursively choosing the middle element of the current array segment as the root, and using the left and right halves to build the subtrees.

Companies: Amazon, Microsoft, Apple

View Python Solution

def sortedArrayToBST(nums: list[int]) -> TreeNode:
    def helper(l, r):
        if l > r:
            return None
    mid = (l + r) // 2
    root = TreeNode(nums[mid])
    root.left = helper(l, mid - 1)
    root.right = helper(mid + 1, r)
    return root

return helper(0, len(nums) - 1)

8. Delete Node in a BST

Concept Tested: Direct implementation of the complex three-case deletion algorithm, with a focus on correctly handling the two-child case by finding and replacing with the in-order successor.

Companies: Amazon, Microsoft, Facebook (Meta)

View Python Solution


def deleteNode(root: TreeNode, key: int) -> TreeNode:
    if not root:
        return None
if key > root.val:
    root.right = deleteNode(root.right, key)
elif key < root.val:
    root.left = deleteNode(root.left, key)
else: # Node to delete found
    if not root.left:
        return root.right
    elif not root.right:
        return root.left
    else:
        # Node has two children: find in-order successor (min in right subtree)
        curr = root.right
        while curr.left:
            curr = curr.left
        root.val = curr.val # Copy successor's value
        root.right = deleteNode(root.right, root.val) # Delete the successor
return root

Pattern: Advanced BST Properties & Combinatorics

9. Unique Binary Search Trees

Concept Tested: A Dynamic Programming problem related to BSTs, specifically Catalan numbers. The number of unique BSTs with n nodes, G(n), is the sum of possibilities where each number i from 1 to n is the root. G(n) = Ξ£ (G(i-1) * G(n-i)) for i in 1...n.

Companies: Amazon, Google, Microsoft

View Python Solution

def numTrees(n: int) -> int:
    dp = [0] * (n + 1)
    dp[0] = 1 # Base case: one way to form an empty tree
    dp[1] = 1 # Base case: one way to form a tree with one node
# Calculate for nodes 2 through n
for i in range(2, n + 1):
    # For a tree with i nodes, iterate through all possible roots (1 to i)
    for j in range(1, i + 1):
        # j-1 nodes in the left subtree, i-j nodes in the right
        dp[i] += dp[j - 1] * dp[i - j]

return dp[n]

10. Recover Binary Search Tree

Concept Tested: A problem where two nodes in a BST have been swapped, violating the property. The solution requires finding these two nodes and swapping them back. This can be done by performing an in-order traversal and finding the one or two "dips" in the otherwise sorted sequence.

Companies: Amazon, Google, Microsoft

View Python Solution


def recoverTree(root: TreeNode) -> None:
    first, second, prev = None, None, TreeNode(float('-inf'))
def inorder(node):
    nonlocal first, second, prev
    if not node:
        return

    inorder(node.left)

    # Find the first misplaced node
    if not first and prev.val >= node.val:
        first = prev

    # Find the second misplaced node
    if first and prev.val >= node.val:
        second = node

    prev = node
    inorder(node.right)

inorder(root)
# Swap the values of the two misplaced nodes
first.val, second.val = second.val, first.val

Heaps

Pattern: Two Heaps

This advanced pattern involves using two heaps simultaneously (usually a max-heap and a min-heap) to partition a stream of data and efficiently find median or percentile values.

6. Find Median from Data Stream

Concept Tested: The canonical "two heaps" problem. You maintain two heaps: a max-heap to store the smaller half of the numbers and a min-heap for the larger half. By keeping the heaps balanced (or differing by at most one element), the median can be calculated in O(1) time from the roots of the heaps.

Companies: Amazon, Google, Facebook (Meta), Microsoft, Apple

View Python Solution

import heapq
class MedianFinder:
    def __init__(self):
        self.small_half = []  # max-heap (using negative numbers)
        self.large_half = []  # min-heap
def addNum(self, num: int) -> None:
    heapq.heappush(self.small_half, -1 * num)
    if (self.small_half and self.large_half and
            (-1 * self.small_half[0]) > self.large_half[0]):
        val = -1 * heapq.heappop(self.small_half)
        heapq.heappush(self.large_half, val)
    if len(self.small_half) > len(self.large_half) + 1:
        val = -1 * heapq.heappop(self.small_half)
        heapq.heappush(self.large_half, val)
    if len(self.large_half) > len(self.small_half) + 1:
        val = heapq.heappop(self.large_half)
        heapq.heappush(self.small_half, -1 * val)

def findMedian(self) -> float:
    if len(self.small_half) > len(self.large_half):
        return -1 * self.small_half[0]
    if len(self.large_half) > len(self.small_half):
        return self.large_half[0]
    return (-1 * self.small_half[0] + self.large_half[0]) / 2.0

Pattern: Merging & Scheduling

These problems use heaps to efficiently merge multiple sorted sources or make greedy scheduling decisions.

7. Merge k Sorted Lists

Concept Tested: A classic problem perfectly solved with a min-heap. The heap stores the head node from each of the k lists. You repeatedly extract the overall minimum node from the heap, add it to your result, and then insert the next node from its original list back into the heap.

Companies: Amazon, Google, Microsoft, Facebook (Meta)

View Python Solution

import heapq
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

def mergeKLists(lists: list[ListNode]) -> ListNode: min_heap = [] for i, l in enumerate(lists): if l: heapq.heappush(min_heap, (l.val, i, l))

dummy = ListNode()
tail = dummy

while min_heap:
    val, i, node = heapq.heappop(min_heap)
    tail.next = node
    tail = tail.next
    if node.next:
        heapq.heappush(min_heap, (node.next.val, i, node.next))

return dummy.next

8. IPO (Find Maximized Capital)

Concept Tested: A challenging problem combining a greedy approach with a heap. First, sort all projects by their required capital. Then, iterate through the sorted projects. For each project you can currently afford, push its profit onto a max-heap. After adding all affordable projects, greedily pick the one with the highest profit from the heap, update your capital, and repeat.

Companies: Google, Amazon

View Python Solution


import heapq
def findMaximizedCapital(k: int, w: int, profits: list[int], capital: list[int]) -> int:
    projects = sorted(zip(capital, profits))
    max_heap = [] # Stores profits of affordable projects
    i = 0
for _ in range(k):
    while i < len(projects) and projects[i][0] <= w:
        heapq.heappush(max_heap, -projects[i][1]) # Use negative for max-heap
        i += 1

    if not max_heap:
        break

    w += -heapq.heappop(max_heap)

return w