One Page to Crack LeetCode


Key Sections

  1. Core Data Structures
  2. Essential Algorithms
  3. Problem-Solving Patterns
  4. Advanced Techniques
  5. Common Problem Categories
  6. Optimization Tips

1. Core Data Structures

Arrays and Strings

  • Operations: Traverse, search, sort, rotate.
  • Key Techniques: Sliding window, prefix sums.
# Sliding Window Example: Maximum Subarray Sum of Size K
def max_subarray_sum_k(arr, k):
    max_sum, window_sum = 0, 0
    start = 0
    for end in range(len(arr)):
        window_sum += arr[end]
        if end >= k - 1:
            max_sum = max(max_sum, window_sum)
            window_sum -= arr[start]
            start += 1
    return max_sum

Linked Lists

  • Operations: Reverse, detect cycles, merge.
# Detect Cycle in Linked List
def has_cycle(head):
    slow, fast = head, head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            return True
    return False

Stacks and Queues

  • Applications: Balanced parentheses, monotonic stacks.
# Balanced Parentheses
def is_valid(s):
    stack = []
    mapping = {')': '(', '}': '{', ']': '['}
    for char in s:
        if char in mapping:
            top = stack.pop() if stack else '#'
            if mapping[char] != top:
                return False
        else:
            stack.append(char)
    return not stack

Trees

  • Traversals: Preorder, Inorder, Postorder.
  • Applications: Lowest common ancestor, diameter of a tree.
# Lowest Common Ancestor
def lca(root, p, q):
    if not root or root == p or root == q:
        return root
    left = lca(root.left, p, q)
    right = lca(root.right, p, q)
    return root if left and right else left or right

Graphs

  • Techniques: DFS, BFS, Union-Find, Dijkstra’s.
# Breadth-First Search
from collections import deque
def bfs(graph, start):
    visited = set()
    queue = deque([start])
    while queue:
        node = queue.popleft()
        if node not in visited:
            visited.add(node)
            print(node, end=" ")
            queue.extend(graph[node])

2. Essential Algorithms

Sorting

  • Techniques: Merge Sort, Quick Sort, Heap Sort.
# Quick Sort
def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)

Dynamic Programming

  • Problems: Knapsack, Longest Increasing Subsequence, Matrix Path.
# Longest Increasing Subsequence
def lis(nums):
    dp = [1] * len(nums)
    for i in range(len(nums)):
        for j in range(i):
            if nums[i] > nums[j]:
                dp[i] = max(dp[i], dp[j] + 1)
    return max(dp)

Backtracking

  • Problems: N-Queens, Permutations, Word Search.
# N-Queens
def solve_n_queens(n):
    def is_safe(board, row, col):
        for i in range(row):
            if board[i][col] == 'Q' or                (col - (row - i) >= 0 and board[i][col - (row - i)] == 'Q') or                (col + (row - i) < n and board[i][col + (row - i)] == 'Q'):
                return False
        return True

    def backtrack(row):
        if row == n:
            result.append([''.join(row) for row in board])
            return
        for col in range(n):
            if is_safe(board, row, col):
                board[row][col] = 'Q'
                backtrack(row + 1)
                board[row][col] = '.'

    result = []
    board = [['.'] * n for _ in range(n)]
    backtrack(0)
    return result

3. Problem-Solving Patterns

Sliding Window

  • Problems: Maximum subarray, longest substring.

Two Pointers

  • Problems: Merge sorted arrays, palindrome check.

Divide and Conquer

  • Problems: Merge sort, binary search.

Greedy

  • Problems: Interval scheduling, Huffman encoding.

Union-Find

  • Problems: Connected components, graph cycles.

4. Advanced Techniques

Segment Trees

  • Range queries and updates.
# Segment Tree Template
class SegmentTree:
    def __init__(self, nums):
        self.n = len(nums)
        self.tree = [0] * (2 * self.n)
        self.build(nums)
    
    def build(self, nums):
        for i in range(self.n):
            self.tree[self.n + i] = nums[i]
        for i in range(self.n - 1, 0, -1):
            self.tree[i] = self.tree[2 * i] + self.tree[2 * i + 1]

    def update(self, index, value):
        pos = index + self.n
        self.tree[pos] = value
        while pos > 0:
            left, right = pos, pos ^ 1
            self.tree[pos // 2] = self.tree[left] + self.tree[right]
            pos //= 2

    def query(self, left, right):
        l, r = left + self.n, right + self.n
        res = 0
        while l < r:
            if l % 2 == 1:
                res += self.tree[l]
                l += 1
            if r % 2 == 1:
                r -= 1
                res += self.tree[r]
            l //= 2
            r //= 2
        return res

Conclusion

This guide provides the concepts, patterns, and code templates required to excel on LeetCode. Practice consistently and revisit challenging topics.

Good luck!