💼

Coding Interview Cheat Sheet

Don't memorize 200 problems — learn the patterns behind them. Solutions are in Python, with Big-O. Examples use classic, public problems (Two Sum, Binary Search, etc.).

🎤 New: watch a full mock interview, narrated
A complete 45-min session — OOP design → DP algorithm → behavioral — both sides of the conversation, with coaching notes.
Read the walkthrough →
🆓 Free vs ⭐ Premium: the 🚀 Start Here track is 100% free — full solutions + the code-along terminal, no account needed. Every other section gives a free taste (one Easy, Medium & Hard); reveal any single locked solution for 10 ⭐, or get Learn Premium to unlock everything and follow along anywhere. See Premium →
Classic ProblemsClassic Problems
Arrays & MatrixArrays & Matrix
StringsStrings
Searching & SortingSearching & Sorting
Sliding WindowSliding Window
Linked ListsLinked Lists
Stacks & QueuesStacks & Queues
Trees & BSTTrees & BST
GraphsGraphs
HeapsHeaps
Recursion & BacktrackingRecursion & Backtracking
Dynamic ProgrammingDynamic Programming
GreedyGreedy
Data Structures & DesignData Structures & Design
JavaJava
Real-world & On-the-jobReal-world & On-the-job
Behavioral & PrepBehavioral & Prep
Mixed & HardestMixed & Hardest
Top 150Top 150

🚀 Start here — free beginner track

Brand new, or just looking around? These 8 classics are completely free — full solutions, run them right in the terminal, no account or credits needed. Work top to bottom, then dip into the rest of the page for depth. (With Learn Premium, every section below works exactly like this one.)

FizzBuzz EASY

Print 1–100, but "Fizz" for multiples of 3, "Buzz" for 5, "FizzBuzz" for both. The classic warm-up — check the most specific case (15) first.

for n in range(1, 101):
    if n % 15 == 0:   print("FizzBuzz")
    elif n % 3 == 0:  print("Fizz")
    elif n % 5 == 0:  print("Buzz")
    else:             print(n)

Reverse a String EASY

Slicing does it in one line; the two-pointer version is what an interviewer wants to see you reason about.

def reverse(s):
    return s[::-1]                 # Pythonic one-liner

def reverse_two_pointer(chars):    # in-place, O(n)
    lo, hi = 0, len(chars) - 1
    while lo < hi:
        chars[lo], chars[hi] = chars[hi], chars[lo]
        lo += 1; hi -= 1
    return chars

Check a Palindrome EASY

A word that reads the same backwards. Compare the string to its reverse.

def is_palindrome(s):
    s = s.lower()
    return s == s[::-1]            # "Racecar" -> True

Find the Largest Number EASY

One pass, tracking the biggest seen so far — the pattern behind countless harder problems.

def largest(nums):
    biggest = nums[0]
    for n in nums[1:]:
        if n > biggest:
            biggest = n
    return biggest                # (built-in shortcut: max(nums))

Count the Vowels EASY

Loop the characters and tally the ones in "aeiou" — a gentle intro to string scanning.

def count_vowels(s):
    return sum(1 for c in s.lower() if c in "aeiou")

Two Sum EASY

The single most common interview opener: return the indices of the two numbers that add to target. A hash map turns O(n²) into O(n).

def two_sum(nums, target):
    seen = {}                          # value -> index
    for i, n in enumerate(nums):
        if target - n in seen:
            return [seen[target - n], i]
        seen[n] = i
    return None                        # no pair found

Fibonacci EASY

Each number is the sum of the two before it. The iterative version is O(n) and uses no recursion stack.

def fib(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a                           # fib(10) -> 55

Binary Search EASY

On a sorted array, halve the search space each step — O(log n). Knowing this cold is non-negotiable.

def binary_search(arr, target):
    lo, hi = 0, len(arr) - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if arr[mid] == target: return mid
        if arr[mid] < target:  lo = mid + 1
        else:                  hi = mid - 1
    return -1                          # not found
Finished all 8? Here's where to go next — there's a lot more free. Every topic below also gives you free sample problems (marked FREE in the left sidebar; locked ones show 🔒). In the sidebar, tap 🆓 Show free only to hide everything locked and see just your free path, then work down in this order:
Arrays → Strings → Searching & Sorting → Sliding Window → Linked Lists → Stacks & Queues → Trees & BST → Graphs → Recursion → Dynamic Programming. When you're ready for the full set, reveal any locked solution for 10 ⭐ or unlock everything with Premium.

Big-O — how fast is your code?

Big-O describes how runtime grows as input size n grows. Lower is better.

Big-ONameExample
O(1)constantlook up a dict/array index
O(log n)logarithmicbinary search
O(n)linearone loop over the data
O(n log n)log-lineargood sorting (merge/quick)
O(n²)quadraticnested loops
O(2ⁿ)exponentialnaive recursion (avoid!)

📊 Complexity reference — operations by data structure

The cost of common operations on each structure. O(1) on hash maps/sets is relative to n — hashing a string key still costs O(m) for a length-m string.

Array / dynamic list (n = len)

OperationBig-O
Add / remove at the endO(1) amortized
Add / remove at arbitrary indexO(n)
Access / modify at indexO(1)
Check if element existsO(n)
Two pointers / sliding windowO(n·k) (k = work per step)
Build a prefix sumO(n)
Subarray sum from a prefix sumO(1)

String — immutable (n = len)

OperationBig-O
Add / remove a characterO(n)
Access at indexO(1)
Concatenate two stringsO(n + m)
Create a substringO(m)
Build via "".join(list)O(n)

Linked list (n = nodes)

OperationBig-O
Add / remove with pointer at spotO(1) (doubly linked)
Add / remove at arbitrary positionO(n)
Access at arbitrary positionO(n)
Reverse between i and jO(j − i)
Detect a cycle (fast/slow)O(n)

Hash map / set (n = size)

OperationBig-O
Add / remove / look up a keyO(1)
Check if a value existsO(n)
Iterate over keys / valuesO(n)

Stack & Queue (n = size)

OperationBig-O
Push / pop / peek (stack)O(1)
Enqueue / dequeue / peek (queue)O(1)
Check if element existsO(n)

Trees, Heaps, Binary search

OperationBig-O
Binary tree DFS / BFSO(n·k) (k = work per node)
BST add / remove / searchO(log n) avg, O(n) worst (unbalanced)
Heap add / remove-minO(log n)
Heap find-minO(1)
Heap check if existsO(n)
Binary searchO(log n)

Misc — sorting, graphs, DP

OperationBig-O
SortingO(n log n)
Graph DFS / BFS (time)O(n·k + e) (n nodes, e edges)
Graph DFS / BFS (space)O(n), or O(n + e) to store the graph
DP (time)O(n·k) (n states, k work/state)
DP (space)O(n) (n states)

Input size → expected Big-O (read the constraints as hints)

Interviewers rarely state constraints out loud — but it never hurts to ask the expected input size. The size strongly hints at the intended complexity:
Constraint on nLikely target complexityThink…
n ≤ 10O(n!) / O(n²·n!)backtracking, brute-force recursion
10 < n ≤ 20O(2ⁿ)subsets/subsequences (take / don't take)
20 < n ≤ 100O(n³)brute force with nested loops
100 < n ≤ 1,000O(n²)nested loops, often optimal here
1,000 < n < 100,000O(n log n) or O(n)sort, heap, hash map, two pointers, monotonic stack, binary search
100,000 < n < 1,000,000O(n)almost certainly a hash map
n > 1,000,000 (or 10⁹+)O(log n) / O(1)binary search, math tricks, clever hashing
Rule of thumb: if the problem must look at every element (e.g. find the max of an unsorted array), you can't beat O(n). Otherwise you usually can't beat O(log n). An O(n) solution can hide a constant factor of ~40 (e.g. looping the 26 letters → O(26n)). Don't be confidently wrong about optimality — "I think this is optimal, but it may be improvable" is the safe phrasing.

🎤 The 7 stages of a coding interview (45–60 min)

A condensed game plan. Remote interview? Keep this in front of you. The meta-skill that ties it all together: think out loud the entire time — it lets the interviewer hint you toward the solution.

1. Introductions

2. Problem statement

3. Brainstorming DS & A

4. Implementation

5. Testing & debugging

6. Explanations & follow-ups

7. Outro

The patterns (this is the real cheat code)

⭐ Code templates (memorize these skeletons)

These are reusable fill-in-the-blank skeletons for every common pattern. Learn the shape once, then for each problem just plug in the specific logic (the CONDITION / # do logic parts). This is the single highest-leverage thing to memorize for interviews.

Two pointers — one input, opposite ends

def fn(arr):
    left = ans = 0
    right = len(arr) - 1
    while left < right:
        # do logic with left and right
        if CONDITION:
            left += 1
        else:
            right -= 1
    return ans

Two pointers — two inputs, exhaust both

def fn(arr1, arr2):
    i = j = ans = 0
    while i < len(arr1) and j < len(arr2):
        # do logic
        if CONDITION:
            i += 1
        else:
            j += 1
    while i < len(arr1):
        # do logic
        i += 1
    while j < len(arr2):
        # do logic
        j += 1
    return ans

Sliding window

def fn(arr):
    left = ans = curr = 0
    for right in range(len(arr)):
        # add arr[right] to curr
        while WINDOW_CONDITION_BROKEN:
            # remove arr[left] from curr
            left += 1
        # update ans
    return ans

Build a prefix sum

Efficient string building

Collect chars in a list, then "".join() — building a string with += in a loop is O(n²) in Python. (In JS, benchmarks show += is actually faster than .join().)

Linked list — fast & slow pointer

Reversing a linked list

Count subarrays that fit an exact criteria

Prefix-count with a hash map (e.g. "subarrays summing to k").

Monotonic increasing stack

Same idea maintains a monotonic queue. For monotonic decreasing, just flip > to <.

Binary tree — DFS (recursive)

Binary tree — DFS (iterative)

Binary tree — BFS (level order)

Graph — DFS (recursive)

Assume nodes 0..n-1 and an adjacency-list graph. Convert other inputs to this form first.

Graph — DFS (iterative)

Graph — BFS

Top k elements with a heap

Binary search

Binary search — left-most insertion point (duplicates)

Binary search — right-most insertion point (duplicates)

Binary search — greedy "search the answer" (minimum)

Binary search — greedy "search the answer" (maximum)

Backtracking

Dynamic programming — top-down memoization

Top-down → bottom-up: (1) make a dp array sized by your state variables (so dp(4,6) becomes dp[4][6]); (2) set the same base cases (often just init to 0); (3) write for-loops over the state variables, iterating from the base cases toward the answer state; (4) copy the recurrence in, turning every dp(...) call into dp[...] array access; (5) return dp[...] instead of dp(...).

Build a trie

Dijkstra's algorithm

Classic Problems

Two Number Sum EASY

Problem: given an array and a target, return two numbers that add up to the target.

Pattern: hash set — for each number, check if target − number was already seen. O(n) time.

def two_number_sum(nums, target):
    seen = set()
    for n in nums:
        complement = target - n
        if complement in seen:
            return [complement, n]
        seen.add(n)
    return []
# two_number_sum([3, 5, -4, 8, 11, 1, -1, 6], 10) -> [11, -1]

Validate Subsequence EASY

Problem: is the second array a subsequence of the first (same order, not necessarily contiguous)?

Pattern: two pointers — walk the main array, advance the second pointer on each match. O(n).

def is_valid_subsequence(array, sequence):
    i = 0
    for value in array:
        if i == len(sequence):
            break
        if sequence[i] == value:
            i += 1
    return i == len(sequence)

Find Three Largest Numbers EASY

Problem: return the 3 largest numbers in sorted order — without fully sorting.

Pattern: a single pass keeping the top 3. O(n).

def three_largest(nums):
    top = [None, None, None]
    for n in nums:
        if top[2] is None or n > top[2]:
            top = [top[1], top[2], n]
        elif top[1] is None or n > top[1]:
            top = [top[1], n, top[2]]
        elif top[0] is None or n > top[0]:
            top = [n, top[1], top[2]]
    return top

Tournament Winner EASY

Transpose Matrix EASY

Product Sum (nested lists) EASY

Minimum Waiting Time EASY

Order shortest jobs first so everyone waits the least. Greedy. O(n log n).

Common Characters EASY

Semordnilap EASY

Pairs where one word is the other reversed (e.g. "diaper"/"repaid"). O(n·len).

Branch Sums (tree) EASY

Node Depths (tree) EASY

3Sum MEDIUM

Problem: Return all unique triples in the array that sum to zero.
def three_sum_classic(nums):
    nums.sort()
    result = []
    for i in range(len(nums) - 2):
        if i > 0 and nums[i] == nums[i-1]:
            continue
        lo, hi = i + 1, len(nums) - 1
        while lo < hi:
            total = nums[i] + nums[lo] + nums[hi]
            if total < 0:
                lo += 1
            elif total > 0:
                hi -= 1
            else:
                result.append([nums[i], nums[lo], nums[hi]])
                while lo < hi and nums[lo] == nums[lo+1]:
                    lo += 1
                while lo < hi and nums[hi] == nums[hi-1]:
                    hi -= 1
                lo += 1
                hi -= 1
    return result

Container With Most Water MEDIUM

Problem: Given heights of vertical lines, return the maximum area of water a container formed by two lines can hold.
def max_area_classic(height):
    lo, hi = 0, len(height) - 1
    best = 0
    while lo < hi:
        best = max(best, min(height[lo], height[hi]) * (hi - lo))
        if height[lo] < height[hi]:
            lo += 1
        else:
            hi -= 1
    return best

Longest Consecutive Sequence MEDIUM

Problem: Return the length of the longest run of consecutive integers present in the array, in O(n).
def longest_consecutive_classic(nums):
    num_set = set(nums)
    best = 0
    for n in num_set:
        if n - 1 not in num_set:
            length = 1
            while n + length in num_set:
                length += 1
            best = max(best, length)
    return best

Subarray Sum Equals K MEDIUM

Problem: Return the number of contiguous subarrays whose elements sum to exactly k, using prefix sums.

Find All Duplicates in an Array MEDIUM

Problem: Every value is in the range 1..n and appears once or twice. Return all values that appear twice, in O(n) time and O(1) extra space.

Majority Element MEDIUM

Problem: Return the element that appears more than n/2 times, using the Boyer-Moore voting algorithm.

Valid Sudoku MEDIUM

Problem: Return True if a 9x9 Sudoku board (with '.' for empty) is valid: no row, column, or 3x3 box has a repeated digit.

Game of Life MEDIUM

Problem: Compute the next state of Conway's Game of Life board in place (encode transitions with intermediate values), then return it.

Insert Interval MEDIUM

Problem: Insert a new interval into a list of sorted non-overlapping intervals, merging any overlaps. Return the result.

H-Index MEDIUM

Problem: Given citation counts per paper, return the researcher's h-index: the largest h such that h papers each have at least h citations.

Maximal Square HARD

Problem: Given a binary matrix, return the area of the largest square containing only 1s (DP on square side length).
def maximal_square_classic(matrix):
    if not matrix:
        return 0
    rows, cols = len(matrix), len(matrix[0])
    dp = [[0] * (cols + 1) for _ in range(rows + 1)]
    best = 0
    for r in range(1, rows + 1):
        for c in range(1, cols + 1):
            if matrix[r-1][c-1] == 1:
                dp[r][c] = min(dp[r-1][c], dp[r][c-1], dp[r-1][c-1]) + 1
                best = max(best, dp[r][c])
    return best * best

Dungeon Game HARD

Problem: A knight starts top-left and must reach the bottom-right of a grid of health deltas, keeping health above 0 at all times. Return the minimum starting health (DP from the goal backward).
def calculate_minimum_hp(dungeon):
    rows, cols = len(dungeon), len(dungeon[0])
    dp = [[float('inf')] * (cols + 1) for _ in range(rows + 1)]
    dp[rows][cols-1] = dp[rows-1][cols] = 1
    for r in range(rows - 1, -1, -1):
        for c in range(cols - 1, -1, -1):
            need = min(dp[r+1][c], dp[r][c+1]) - dungeon[r][c]
            dp[r][c] = max(1, need)
    return dp[0][0]

Longest Increasing Path in a Matrix HARD

Problem: Return the length of the longest strictly increasing path in a matrix, moving up/down/left/right (memoized DFS).
def longest_increasing_path(matrix):
    if not matrix:
        return 0
    rows, cols = len(matrix), len(matrix[0])
    memo = {}
    def dfs(r, c):
        if (r, c) in memo:
            return memo[(r, c)]
        best = 1
        for dr, dc in ((1,0),(-1,0),(0,1),(0,-1)):
            nr, nc = r + dr, c + dc
            if 0 <= nr < rows and 0 <= nc < cols and matrix[nr][nc] > matrix[r][c]:
                best = max(best, 1 + dfs(nr, nc))
        memo[(r, c)] = best
        return best
    return max(dfs(r, c) for r in range(rows) for c in range(cols))

Best Time to Buy and Sell Stock III HARD

Problem: You may complete at most two transactions (buy then sell). Return the maximum profit.

Best Time to Buy and Sell Stock IV HARD

Problem: You may complete at most k transactions. Return the maximum profit.

Burst Balloons HARD

Problem: Bursting balloon i earns nums[left]*nums[i]*nums[right] (neighbors after removals). Return the maximum coins from bursting all balloons (interval DP).

Russian Doll Envelopes HARD

Problem: Each envelope is [width, height]; one fits inside another only if both dimensions are strictly greater. Return the maximum number of nested envelopes.

Minimum Window Subsequence HARD

Problem: Return the smallest contiguous substring of s that contains t as a subsequence, or '' if none exists.

Largest Number HARD

Problem: Arrange the non-negative integers so that concatenating them forms the largest possible number. Return it as a string.

Max Points on a Line HARD

Problem: Given points on a plane, return the maximum number of points that lie on the same straight line.

Arrays & Matrix

Sorted Squared Array EASY

Square each number of a sorted array, return sorted. Two pointers from both ends (largest squares are at the ends). O(n).

class Solution:
    def sorted_squared(self, arr):
        res = [0] * len(arr)
        lo, hi = 0, len(arr) - 1
        for i in range(len(arr) - 1, -1, -1):
            if abs(arr[lo]) > abs(arr[hi]):
                res[i] = arr[lo] ** 2; lo += 1
            else:
                res[i] = arr[hi] ** 2; hi -= 1
        return res

Move Element To End EASY

Move all copies of a value to the end, in place. Two pointers. O(n).

class Solution:
    def move_to_end(self, arr, target):
        lo, hi = 0, len(arr) - 1
        while lo < hi:
            while lo < hi and arr[hi] == target: hi -= 1
            if arr[lo] == target:
                arr[lo], arr[hi] = arr[hi], arr[lo]
            lo += 1
        return arr

Monotonic Array EASY

Is the array entirely non-increasing or non-decreasing? One pass. O(n).

class Solution:
    def is_monotonic(self, arr):
        up = all(arr[i] <= arr[i+1] for i in range(len(arr)-1))
        down = all(arr[i] >= arr[i+1] for i in range(len(arr)-1))
        return up or down

Generate Document EASY

Best Seat EASY

Running Sum of 1D Array EASY

Problem: Return the running (prefix) sum of the array, where output[i] is the sum of nums[0..i].

Max Consecutive Ones EASY

Problem: Given a binary array, return the length of the longest run of consecutive 1s.

Move Zeroes EASY

Problem: Move all zeroes to the end of the array while keeping the order of non-zero elements, then return it.

Two Sum II (Sorted Input) EASY

Problem: Given a sorted array, return the 1-based indices of the two numbers that add up to target, using two pointers.

Plus One EASY

Problem: A non-negative integer is stored as a digit array (most significant first). Add one and return the resulting digit array.

Single Number EASY

Problem: Every element appears twice except one. Return the element that appears only once, using XOR in O(n) time and O(1) space.

Three Number Sum MEDIUM

Find all triplets that sum to the target. Sort, then for each number use two pointers. O(n²).

class Solution:
    def three_number_sum(self, nums, target):
        nums.sort()
        res = []
        for i in range(len(nums) - 2):
            lo, hi = i + 1, len(nums) - 1
            while lo < hi:
                s = nums[i] + nums[lo] + nums[hi]
                if s == target:
                    res.append([nums[i], nums[lo], nums[hi]]); lo += 1; hi -= 1
                elif s < target: lo += 1
                else: hi -= 1
        return res

Smallest Difference MEDIUM

Pick one number from each array so their difference is smallest. Sort both, walk two pointers. O(n log n).

class Solution:
    def smallest_difference(self, a, b):
        a.sort(); b.sort()
        i = j = 0; best = float("inf"); pair = []
        while i < len(a) and j < len(b):
            if abs(a[i] - b[j]) < best:
                best = abs(a[i] - b[j]); pair = [a[i], b[j]]
            if a[i] < b[j]: i += 1
            elif a[i] > b[j]: j += 1
            else: return [a[i], b[j]]
        return pair

Array Of Products MEDIUM

Each output[i] = product of all other numbers — without division. Prefix & suffix products. O(n).

class Solution:
    def array_of_products(self, arr):
        n = len(arr); res = [1] * n
        left = 1
        for i in range(n):
            res[i] = left; left *= arr[i]
        right = 1
        for i in range(n - 1, -1, -1):
            res[i] *= right; right *= arr[i]
        return res

First Duplicate Value MEDIUM

Return the first value that appears twice. Hash set. O(n).

Merge Overlapping Intervals MEDIUM

Combine overlapping [start, end] ranges. Sort by start, then merge. O(n log n).

Kadane's Algorithm — Max Subarray Sum MEDIUM

Largest sum of any contiguous subarray. Track best ending here vs. restart. O(n).

Zigzag Traverse MEDIUM

Subarray Sort MEDIUM

Smallest subarray that, if sorted, makes the whole array sorted. O(n).

Largest Range MEDIUM

Longest run of consecutive integers (any order). Hash set. O(n).

Min Rewards MEDIUM

Give each child ≥1 reward; a higher score than a neighbor needs more. Two passes. O(n).

Single Cycle Check MEDIUM

Jumping by each value, do you visit every index exactly once and land back at the start? O(n).

Valid Starting City MEDIUM

Circular road of cities with fuel — find the only city you can start from and finish the loop. O(n).

Majority Element (Boyer-Moore) MEDIUM

The element appearing > n/2 times — in O(n) time, O(1) space.

Task Assignment MEDIUM

Pair tasks for k workers (2 each) to minimize total time — pair fastest with slowest. O(n log n).

Missing Numbers (two missing from 1..n) MEDIUM

Minimum Area Rectangle MEDIUM

Smallest axis-aligned rectangle from a set of points. Check diagonal corner pairs. O(n²).

Maximum Sum Submatrix (fixed size) MEDIUM

Largest sum of any size×size square. 2-D prefix sums. O(w·h).

Spiral Traverse MEDIUM

Read a matrix in a spiral. Shrink four borders inward. O(n).

Longest Peak MEDIUM

Length of the longest "up then down" run. Find each peak, expand both ways. O(n).

Three Number Sort (Dutch flag) MEDIUM

Sort an array containing three distinct values, in place, in one pass. O(n).

Min Number Of Jumps MEDIUM

Fewest jumps to reach the end, where each value is the max jump length. Greedy. O(n).

Reveal Minesweeper MEDIUM

Click a cell: a mine → "X"; otherwise show the mine count, and flood-fill zeros. "M"=mine, "H"=hidden.

Four Number Sum HARD

All quadruplets summing to target. Hash pair-sums while scanning. Average O(n²).

class Solution:
    def four_number_sum(self, nums, target):
        pair_sums = {}; res = []
        for i in range(1, len(nums) - 1):
            for j in range(i + 1, len(nums)):
                need = target - (nums[i] + nums[j])
                for pair in pair_sums.get(need, []):
                    res.append(pair + [nums[i], nums[j]])
            for k in range(i):
                s = nums[i] + nums[k]
                pair_sums.setdefault(s, []).append([nums[k], nums[i]])
        return res

Largest Rectangle Under Skyline HARD

Biggest rectangle in a histogram. Monotonic stack of increasing heights. O(n).

class Solution:
    def largest_rectangle(self, heights):
        stack = []; best = 0
        for i, h in enumerate(heights + [0]):     # sentinel flushes the stack
            while stack and heights[stack[-1]] >= h:
                height = heights[stack.pop()]
                width = i if not stack else i - stack[-1] - 1
                best = max(best, height * width)
            stack.append(i)
        return best

Apartment Hunting HARD

Pick the block minimizing the max distance to every requirement. Precompute nearest each side. O(b·r).

class Solution:
    def apartment_hunting(self, blocks, reqs):
        n = len(blocks); dists = []
        for req in reqs:
            closest = [float("inf")] * n; nearest = float("inf")
            for i in range(n):
                if blocks[i][req]: nearest = i
                closest[i] = abs(i - nearest)
            for i in range(n - 1, -1, -1):
                if blocks[i][req]: nearest = i
                closest[i] = min(closest[i], abs(i - nearest))
            dists.append(closest)
        best, best_max = 0, float("inf")
        for i in range(n):
            worst = max(d[i] for d in dists)
            if worst < best_max: best_max, best = worst, i
        return best

Water Area (trapping rain) HARD

Water trapped above each bar = min(tallest left, tallest right) − its height. O(n).

Trapping Rain Water (Two Pointers) HARD

Problem: Given an elevation map, compute how much water it can trap after raining, using two pointers in O(n) time and O(1) space.

Product of Array Except Self HARD

Problem: Return an array where each element is the product of all other elements, without using division and in O(n).

First Missing Positive HARD

Problem: Return the smallest positive integer missing from the array in O(n) time and O(1) extra space (index placement).

Maximum Product Subarray HARD

Problem: Return the largest product of any contiguous subarray, tracking both the running max and min (for negatives).

Spiral Matrix HARD

Problem: Return all elements of the matrix in spiral order (clockwise from the top-left).

Rotate Image HARD

Problem: Rotate an n x n matrix 90 degrees clockwise in place (transpose then reverse each row), then return it.

Set Matrix Zeroes HARD

Problem: If a cell is 0, set its entire row and column to 0. Do it in place using the first row/column as markers, then return the matrix.

Strings

Palindrome Check EASY

class Solution:
    def is_palindrome(self, s):
        lo, hi = 0, len(s) - 1
        while lo < hi:
            if s[lo] != s[hi]: return False
            lo += 1; hi -= 1
        return True
    # or simply: return s == s[::-1]

Caesar Cipher Encryptor EASY

Shift each letter by a key (wrapping around the alphabet). O(n).

class Solution:
    def caesar_cipher(self, s, key):
        out = []
        for ch in s:
            code = (ord(ch) - ord("a") + key) % 26
            out.append(chr(ord("a") + code))
        return "".join(out)

First Non-Repeating Character EASY

class Solution:
    def first_non_repeating(self, s):
        counts = {}
        for ch in s: counts[ch] = counts.get(ch, 0) + 1
        for i, ch in enumerate(s):
            if counts[ch] == 1: return i
        return -1

Run-Length Encoding EASY

Reverse the Word Order EASY

Problem: Reverse the order of words in a sentence, collapsing extra spaces (e.g. 'the sky is blue' -> 'blue is sky the').

Valid Anagram EASY

Problem: Return True if t is an anagram of s (same characters with the same counts).

First Unique Character EASY

Problem: Return the index of the first non-repeating character in the string, or -1 if there is none.

Capitalize Each Word EASY

Problem: Return the string with the first letter of each word capitalized and the rest lowercased.

Remove Vowels EASY

Problem: Return the string with all vowels (a, e, i, o, u) removed.

Longest Common Prefix EASY

Problem: Return the longest common prefix shared by all strings in the list ('' if none).

Valid Palindrome (Alphanumeric) EASY

Problem: Return True if the string is a palindrome considering only alphanumeric characters and ignoring case.

Reverse Only Letters EASY

Problem: Reverse only the letters of the string, leaving every non-letter character in its original position.

Longest Palindromic Substring MEDIUM

Expand around every center (odd & even). O(n²).

class Solution:
    def longest_palindrome(self, s):
        res = ""
        def expand(l, r):
            while l >= 0 and r < len(s) and s[l] == s[r]:
                l -= 1; r += 1
            return s[l+1:r]
        for i in range(len(s)):
            for cand in (expand(i, i), expand(i, i+1)):
                if len(cand) > len(res): res = cand
        return res

Group Anagrams MEDIUM

class Solution:
    def group_anagrams(self, words):
        groups = {}
        for w in words:
            key = "".join(sorted(w))
            groups.setdefault(key, []).append(w)
        return list(groups.values())

Valid IP Addresses MEDIUM

class Solution:
    def valid_ip_addresses(self, s):
        res = []
        def ok(part):
            return len(part) == 1 or (part[0] != "0" and int(part) <= 255)
        for a in range(1, 4):
            for b in range(a+1, a+4):
                for c in range(b+1, b+4):
                    p1, p2, p3, p4 = s[:a], s[a:b], s[b:c], s[c:]
                    if 1 <= len(p4) <= 3 and all(ok(p) for p in (p1,p2,p3,p4)):
                        res.append(f"{p1}.{p2}.{p3}.{p4}")
        return res

Reverse Words In String MEDIUM

One Edit Away MEDIUM

Are two strings at most one insert/delete/replace apart? O(n).

Sweet And Savory MEDIUM

Pick one negative (sweet) + one positive (savory) dish with sum closest to target without exceeding it. Two pointers. O(n log n).

Group Anagrams MEDIUM

Problem: Group the strings that are anagrams of one another. Return the groups as a list of lists.

String Compression MEDIUM

Problem: Compress a string by replacing runs of the same character with the character followed by its count, e.g. 'aabcccccaaa' -> 'a2b1c5a3'.

Count and Say MEDIUM

Problem: Generate the nth term of the count-and-say sequence, where each term describes the digit runs of the previous term.

Zigzag Conversion MEDIUM

Problem: Write the string in a zigzag pattern across the given number of rows, then read it off row by row.

Multiply Strings MEDIUM

Problem: Multiply two non-negative integers given as strings, without using built-in big-integer conversion of the whole number. Return the product as a string.

String to Integer (atoi) MEDIUM

Problem: Convert a string to a 32-bit signed integer following atoi rules: skip leading spaces, optional sign, read digits, and clamp to the 32-bit range.

Longest Substring Without Duplicates HARD

Sliding window + a map of last-seen positions. O(n).

class Solution:
    def longest_unique_substring(self, s):
        seen = {}; start = 0; best = [0, 1]
        for i, ch in enumerate(s):
            if ch in seen and seen[ch] >= start:
                start = seen[ch] + 1
            if i + 1 - start > best[1] - best[0]:
                best = [start, i + 1]
            seen[ch] = i
        return s[best[0]:best[1]]

Underscorify Substring HARD

Wrap every occurrence of a substring with underscores, merging overlaps. O(n+m).

class Solution:
    def underscorify_substring(self, string, substring):
        locs = []; start = 0
        while True:
            i = string.find(substring, start)
            if i == -1: break
            locs.append([i, i + len(substring)]); start = i + 1
        merged = []
        for loc in locs:
            if merged and loc[0] <= merged[-1][1]:
                merged[-1][1] = max(merged[-1][1], loc[1])
            else: merged.append(loc)
        out = []; m = 0
        for i in range(len(string) + 1):
            if m < len(merged) and i == merged[m][0]: out.append("_")
            if m < len(merged) and i == merged[m][1]: out.append("_"); m += 1
            if i < len(string): out.append(string[i])
        return "".join(out)

Multi String Search HARD

Which small strings appear inside the big string? Build a trie of the big string's suffixes.

class Solution:
    def multi_string_search(self, big, small):
        trie = {}
        for i in range(len(big)):                 # all suffixes
            node = trie
            for ch in big[i:]:
                node = node.setdefault(ch, {})
        def contains(word):
            node = trie
            for ch in word:
                if ch not in node: return False
                node = node[ch]
            return True
        return [contains(w) for w in small]

Regular Expression Matching HARD

Problem: Implement matching for '.' (any single char) and '*' (zero or more of the preceding element) covering the entire input string.

Wildcard Matching HARD

Problem: Implement matching for '?' (any single char) and '*' (any sequence including empty) covering the entire input string.

Edit Distance HARD

Problem: Return the minimum number of single-character insertions, deletions, or replacements needed to turn word1 into word2.

Text Justification HARD

Problem: Given words and a maximum line width, format the text so each line is fully justified (extra spaces distributed left-first); the last line is left-justified. Return the list of lines.

Integer to English Words HARD

Problem: Convert a non-negative integer to its English words representation, e.g. 1234567 -> 'One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven'.

Distinct Subsequences HARD

Problem: Return the number of distinct subsequences of s that equal t.

Shortest Palindrome HARD

Problem: Find the shortest palindrome you can make by adding characters only to the front of the string.

Palindrome Partitioning II (Min Cuts) HARD

Problem: Return the minimum number of cuts needed to partition the string so that every part is a palindrome.

Searching & Sorting

Binary Search EASY

Problem: find a target's index in a sorted array.

Pattern: halve the search range each step. O(log n).

def binary_search(arr, target):
    low, high = 0, len(arr) - 1
    while low <= high:
        mid = (low + high) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            low = mid + 1
        else:
            high = mid - 1
    return -1

Binary Search EASY

Problem: Return the index of target in a sorted array, or -1 if it is not present.
def binary_search_searchsort(nums, target):
    lo, hi = 0, len(nums) - 1
    while lo <= hi:
        mid = lo + (hi - lo) // 2
        if nums[mid] == target:
            return mid
        if nums[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1

Bubble Sort EASY

Problem: Sort an array ascending using bubble sort and return it.
def bubble_sort_searchsort(nums):
    a = list(nums)
    for i in range(len(a) - 1):
        swapped = False
        for j in range(len(a) - 1 - i):
            if a[j] > a[j+1]:
                a[j], a[j+1] = a[j+1], a[j]
                swapped = True
        if not swapped:
            break
    return a

Selection Sort EASY

Problem: Sort an array ascending using selection sort and return it.

Insertion Sort EASY

Problem: Sort an array ascending using insertion sort and return it.

First Occurrence in a Sorted Array EASY

Problem: Return the index of the first occurrence of target in a sorted array with duplicates, or -1.

Last Occurrence in a Sorted Array EASY

Problem: Return the index of the last occurrence of target in a sorted array with duplicates, or -1.

Search Insert Position EASY

Problem: Return the index where target is found in a sorted array, or the index where it would be inserted to keep it sorted.

Is the Array Sorted EASY

Problem: Return True if the array is sorted in non-decreasing order.

Count Occurrences in a Sorted Array EASY

Problem: Return how many times target appears in a sorted array, using binary search for the boundaries.

Integer Square Root EASY

Problem: Return the floor of the square root of a non-negative integer x, using binary search.

Search For Range MEDIUM

First and last index of a target in a sorted array. Two binary searches. O(log n).

class Solution:
    def search_range(self, arr, target):
        def bound(left):
            lo, hi, res = 0, len(arr) - 1, -1
            while lo <= hi:
                mid = (lo + hi) // 2
                if arr[mid] == target:
                    res = mid
                    if left: hi = mid - 1
                    else:    lo = mid + 1
                elif arr[mid] < target: lo = mid + 1
                else: hi = mid - 1
            return res
        return [bound(True), bound(False)]

Search In Sorted Matrix MEDIUM

Rows & columns both sorted. Start top-right, move left/down. O(n+m).

class Solution:
    def search_matrix(self, matrix, target):
        row, col = 0, len(matrix[0]) - 1
        while row < len(matrix) and col >= 0:
            if matrix[row][col] == target: return [row, col]
            elif matrix[row][col] > target: col -= 1
            else: row += 1
        return [-1, -1]

Bubble / Insertion / Selection (O(n²))

class Solution:
    def bubble_sort(self, a):
        for i in range(len(a)):
            for j in range(len(a) - 1 - i):
                if a[j] > a[j+1]: a[j], a[j+1] = a[j+1], a[j]
        return a

    def insertion_sort(self, a):
        for i in range(1, len(a)):
            j = i
            while j > 0 and a[j] < a[j-1]:
                a[j], a[j-1] = a[j-1], a[j]; j -= 1
        return a

    def selection_sort(self, a):
        for i in range(len(a)):
            m = i
            for j in range(i+1, len(a)):
                if a[j] < a[m]: m = j
            a[i], a[m] = a[m], a[i]
        return a

Quick Sort & Merge Sort (O(n log n))

Search in Rotated Sorted Array MEDIUM

Problem: A sorted array was rotated at an unknown pivot. Return the index of target, or -1, in O(log n).

Find Minimum in Rotated Sorted Array MEDIUM

Problem: Return the minimum element of a rotated sorted array with distinct values, in O(log n).

Find Peak Element MEDIUM

Problem: A peak is an element strictly greater than its neighbors. Return the index of any peak in O(log n).

Merge Sort MEDIUM

Problem: Sort an array ascending using recursive merge sort and return it.

Quicksort MEDIUM

Problem: Sort an array ascending using quicksort and return it.

Kth Largest via Quickselect MEDIUM

Problem: Return the kth largest element using the quickselect partitioning method (average O(n)).

Sort Colors (Dutch National Flag) MEDIUM

Problem: Sort an array of 0s, 1s, and 2s in place in one pass, then return it.

First Bad Version MEDIUM

Problem: Versions 1..n exist; from some version on, all are bad. Given the first bad version, return it using the fewest checks (binary search).

Search a 2D Matrix MEDIUM

Problem: In a matrix where each row is sorted and each row's first value exceeds the previous row's last, return True if target is present (treat it as one sorted list).

Shifted Binary Search HARD

Binary search in a rotated sorted array. Decide which half is sorted each step. O(log n).

class Solution:
    def shifted_binary_search(self, arr, target):
        lo, hi = 0, len(arr) - 1
        while lo <= hi:
            mid = (lo + hi) // 2
            if arr[mid] == target: return mid
            if arr[lo] <= arr[mid]:                  # left half sorted
                if arr[lo] <= target < arr[mid]: hi = mid - 1
                else: lo = mid + 1
            else:                                    # right half sorted
                if arr[mid] < target <= arr[hi]: lo = mid + 1
                else: hi = mid - 1
        return -1

Quickselect — kth smallest HARD

Like quicksort but only recurse into the side with the answer. Average O(n).

class Solution:
    def quickselect(self, arr, k):           # k is 1-indexed position
        lo, hi = 0, len(arr) - 1
        while True:
            pivot = arr[hi]; p = lo
            for i in range(lo, hi):
                if arr[i] < pivot:
                    arr[i], arr[p] = arr[p], arr[i]; p += 1
            arr[p], arr[hi] = arr[hi], arr[p]
            if p == k - 1: return arr[p]
            elif p < k - 1: lo = p + 1
            else: hi = p - 1

Radix Sort HARD

Non-comparison sort for non-negative ints — bucket by each digit. O(d·n).

class Solution:
    def radix_sort(self, arr):
        if not arr: return arr
        max_val = max(arr); exp = 1
        while max_val // exp > 0:
            buckets = [[] for _ in range(10)]
            for num in arr:
                buckets[(num // exp) % 10].append(num)
            arr = [num for bucket in buckets for num in bucket]
            exp *= 10
        return arr

Count Inversions HARD

How many pairs are out of order? Piggyback on merge sort. O(n log n).

Median of Two Sorted Arrays HARD

Problem: Return the median of two sorted arrays in O(log(min(m,n))) using a binary-search partition.

Search a 2D Matrix II HARD

Problem: In a matrix sorted ascending along both rows and columns, return True if target is present, in O(m+n).

Find K-th Smallest Pair Distance HARD

Problem: Return the kth smallest absolute difference among all pairs, using binary search on the distance plus a sliding window count.

Split Array Largest Sum HARD

Problem: Split the array into k non-empty contiguous parts to minimize the largest part sum. Return that minimized value (binary search on the answer).

Count of Smaller Numbers After Self HARD

Problem: For each element, count how many numbers to its right are smaller. Return the list of counts (merge-sort based).

Koko Eating Bananas HARD

Problem: Koko eats at k bananas/hour, finishing one pile per hour (leftovers count as a full hour). Return the minimum integer k to eat all piles within h hours.

Capacity to Ship Packages in D Days HARD

Problem: Packages must ship in order within d days. Return the least ship capacity (per day) that gets everything shipped in time (binary search on capacity).

Sliding Window

Maximum Sum Subarray of Size K EASY

Problem: Given an array of integers and a number k, find the maximum sum of any contiguous subarray of size k.
def max_sum_subarray_k(nums, k):
    window = sum(nums[:k])
    best = window
    for i in range(k, len(nums)):
        window += nums[i] - nums[i - k]
        best = max(best, window)
    return best

Minimum Sum Subarray of Size K EASY

Problem: Find the minimum sum of any contiguous subarray of size k.
def min_sum_subarray_k(nums, k):
    window = sum(nums[:k])
    best = window
    for i in range(k, len(nums)):
        window += nums[i] - nums[i - k]
        best = min(best, window)
    return best

Averages of All Subarrays of Size K EASY

Problem: Return a list of the averages of every contiguous subarray of size k.
def average_of_subarrays_k(nums, k):
    out, window = [], sum(nums[:k])
    out.append(window / k)
    for i in range(k, len(nums)):
        window += nums[i] - nums[i - k]
        out.append(window / k)
    return out

Maximum Vowels in a Substring of Length K EASY

Problem: Given a string s and integer k, return the maximum number of vowels in any substring of length k.

Contains Duplicate Within Distance K EASY

Problem: Return True if there are two equal values in the array whose indices differ by at most k.

First Negative in Every Window of Size K EASY

Problem: For every contiguous window of size k, report the first negative number (or 0 if the window has none).

Count Windows of Size K With Sum At Least Target EASY

Problem: Count how many contiguous subarrays of size k have a sum greater than or equal to target.

Maximum Ones in a Window of Size K EASY

Problem: Given a binary array, return the greatest number of 1s contained in any window of size k.

Start Index of the Best Window of Size K EASY

Problem: Return the starting index of the size-k window with the largest sum (smallest index on ties).

Does a Window of Size K Sum to Target EASY

Problem: Return True if some contiguous subarray of size k sums to exactly target.

Sliding Window — max subarray sum MEDIUM

Problem: the largest sum of any k consecutive numbers.

Pattern: keep a running window sum; slide it instead of recomputing. O(n).

def max_subarray_sum(nums, k):
    window = sum(nums[:k])
    best = window
    for i in range(k, len(nums)):
        window += nums[i] - nums[i - k]   # add new, drop old
        best = max(best, window)
    return best

Longest Substring Without Repeating Characters MEDIUM

Problem: Return the length of the longest substring of s that has no repeating characters.
def length_of_longest_substring_window(s):
    seen, left, best = {}, 0, 0
    for right, c in enumerate(s):
        if c in seen and seen[c] >= left:
            left = seen[c] + 1
        seen[c] = right
        best = max(best, right - left + 1)
    return best

Longest Substring With At Most K Distinct Characters MEDIUM

Problem: Return the length of the longest substring that contains at most k distinct characters.
def longest_substring_k_distinct(s, k):
    from collections import defaultdict
    count, left, best = defaultdict(int), 0, 0
    for right, c in enumerate(s):
        count[c] += 1
        while len(count) > k:
            count[s[left]] -= 1
            if count[s[left]] == 0:
                del count[s[left]]
            left += 1
        best = max(best, right - left + 1)
    return best

Minimum Size Subarray Sum MEDIUM

Problem: Return the minimal length of a contiguous subarray whose sum is >= target, or 0 if none exists.

Max Consecutive Ones After Flipping K Zeros MEDIUM

Problem: Given a binary array, return the longest run of 1s you can get by flipping at most k zeros.

Longest Repeating Character Replacement MEDIUM

Problem: You may replace at most k characters. Return the length of the longest substring of one repeating letter you can form.

Permutation in String MEDIUM

Problem: Return True if s2 contains a permutation of s1 as a contiguous substring.

Find All Anagrams in a String MEDIUM

Problem: Return the start indices of every substring of s that is an anagram of p.

Fruit Into Baskets MEDIUM

Problem: You can carry at most two types of fruit. Return the most fruit you can pick from a contiguous stretch of trees.

Subarray Product Less Than K MEDIUM

Problem: Count the contiguous subarrays whose product of elements is strictly less than k.

Maximum Frequency After K Increments MEDIUM

Problem: You may add 1 to an element up to k times total. Return the highest frequency of any single value you can reach.

Smallest Substring Containing HARD

Smallest window of big that contains every char of small (minimum window substring). O(n).

from collections import Counter

class Solution:
    def smallest_substring(self, big, small):
        need = Counter(small); missing = len(small)
        left = 0; best = ""
        for right, ch in enumerate(big):
            if need[ch] > 0: missing -= 1
            need[ch] -= 1
            while missing == 0:                     # window has everything
                if not best or right - left + 1 < len(best):
                    best = big[left:right + 1]
                need[big[left]] += 1
                if need[big[left]] > 0: missing += 1
                left += 1
        return best

Minimum Window Substring HARD

Problem: Return the smallest substring of s that contains every character of t (with multiplicity), or '' if none.
def min_window_window(s, t):
    from collections import Counter
    if not t or not s:
        return ""
    need = Counter(t)
    missing = len(t)
    left = start = end = 0
    for right, c in enumerate(s, 1):
        if need[c] > 0:
            missing -= 1
        need[c] -= 1
        if missing == 0:
            while need[s[left]] < 0:
                need[s[left]] += 1
                left += 1
            if end == 0 or right - left < end - start:
                start, end = left, right
            need[s[left]] += 1
            missing += 1
            left += 1
    return s[start:end]

Sliding Window Maximum HARD

Problem: Return a list of the maximum of every contiguous window of size k, using a monotonic deque in O(n).
def max_sliding_window(nums, k):
    from collections import deque
    dq, out = deque(), []
    for i, n in enumerate(nums):
        while dq and nums[dq[-1]] <= n:
            dq.pop()
        dq.append(i)
        if dq[0] <= i - k:
            dq.popleft()
        if i >= k - 1:
            out.append(nums[dq[0]])
    return out

Subarrays With K Different Integers HARD

Problem: Count contiguous subarrays that contain exactly k distinct integers (atMost(k) - atMost(k-1) trick).

Shortest Subarray With Sum At Least K HARD

Problem: With possibly-negative numbers, return the length of the shortest subarray with sum >= k (or -1). Uses prefix sums + a monotonic deque.

Longest Subarray With Absolute Diff Within Limit HARD

Problem: Return the length of the longest subarray where the difference between its max and min is at most limit (two monotonic deques).

Binary Subarrays With Sum HARD

Problem: In a 0/1 array, count the contiguous subarrays whose sum equals goal (atMost(goal) - atMost(goal-1)).

Count Nice Subarrays (Exactly K Odd Numbers) HARD

Problem: Count contiguous subarrays containing exactly k odd numbers (atMost trick on odd counts).

Maximum Points From Cards HARD

Problem: Take exactly k cards from either end of the row; return the maximum total score (minimize the untaken middle window).

Minimum Operations to Reduce X to Zero HARD

Problem: Remove elements from either end so their sum equals x; return the fewest removals (found as the longest middle subarray summing to total - x).

Max Consecutive Ones After Deleting One Element HARD

Problem: Given a binary array, you must delete exactly one element; return the longest run of 1s in the result.

Linked Lists

Merge Two Sorted Lists EASY

class Solution:
    def merge_two_lists(self, l1, l2):
        dummy = Node(0); tail = dummy
        while l1 and l2:
            if l1.value <= l2.value: tail.next = l1; l1 = l1.next
            else: tail.next = l2; l2 = l2.next
            tail = tail.next
        tail.next = l1 or l2
        return dummy.next

Middle Node EASY

class Solution:
    def middle_node(self, head):
        slow = fast = head
        while fast and fast.next:
            slow = slow.next; fast = fast.next.next
        return slow

Remove Duplicates From Linked List EASY

(sorted list — drop consecutive equal nodes). O(n).

class Solution:
    def dedup_sorted_list(self, head):
        node = head
        while node:
            while node.next and node.next.value == node.value:
                node.next = node.next.next
            node = node.next
        return head

Reverse a Linked List EASY

Problem: Reverse a singly linked list and return the new head.

Middle of the Linked List EASY

Problem: Return the value at the middle node. For an even-length list, return the second of the two middle nodes.

Length of a Linked List EASY

Problem: Return the number of nodes in the linked list.

Sum of a Linked List EASY

Problem: Return the sum of all node values in the linked list.

Maximum Value in a Linked List EASY

Problem: Return the largest value stored in the linked list.

Nth Node From the End EASY

Problem: Return the value of the nth node counting from the end (n=1 is the last node).

Delete All Nodes With a Value EASY

Problem: Remove every node whose value equals target and return the head of the resulting list.

Count Occurrences in a Linked List EASY

Problem: Return how many nodes hold the given value.

Search a Linked List EASY

Problem: Return True if the value appears anywhere in the linked list.

Remove Duplicates From a Sorted List EASY

Problem: Given a sorted linked list, remove duplicate values so each appears once. Return the head.

Reverse a Linked List MEDIUM

Problem: reverse the direction of a singly linked list.

Pattern: walk the list, flipping each next pointer. O(n) time, O(1) space.

def reverse_list(head):
    prev = None
    while head:
        nxt = head.next      # save the next node
        head.next = prev     # flip the pointer
        prev = head          # move prev forward
        head = nxt           # move head forward
    return prev               # new head

Remove Kth Node From End MEDIUM

Two pointers k apart; when the fast one ends, slow is at the node before the target. O(n).

class Solution:
    def remove_kth_from_end(self, head, k):
        fast = slow = head
        for _ in range(k): fast = fast.next
        if fast is None: return head.next      # removing the head
        while fast.next:
            fast = fast.next; slow = slow.next
        slow.next = slow.next.next
        return head

Sum of Linked Lists MEDIUM

Two numbers stored as digit lists (ones digit first) — add them. O(n).

class Solution:
    def sum_lists(self, l1, l2):
        dummy = Node(0); cur = dummy; carry = 0
        while l1 or l2 or carry:
            total = carry
            if l1: total += l1.value; l1 = l1.next
            if l2: total += l2.value; l2 = l2.next
            carry, digit = divmod(total, 10)
            cur.next = Node(digit); cur = cur.next
        return dummy.next

Node Swap (swap adjacent pairs) MEDIUM

Find Loop — Floyd's cycle detection MEDIUM

Detect where a linked list loops back. Slow/fast pointers, then reset one to the head. O(n), O(1).

Remove Nth Node From End MEDIUM

Problem: Remove the nth node from the end of the list and return the head.

Merge Two Sorted Lists MEDIUM

Problem: Merge two sorted linked lists into one sorted list and return its head.

Palindrome Linked List MEDIUM

Problem: Return True if the linked list reads the same forwards and backwards.

Odd Even Linked List MEDIUM

Problem: Group all odd-indexed nodes followed by the even-indexed nodes (by position, 1-based), keeping relative order. Return the head.

Swap Nodes in Pairs MEDIUM

Problem: Swap every two adjacent nodes and return the head (swap the nodes themselves, not just values).

Rotate List MEDIUM

Problem: Rotate the linked list to the right by k places and return the head.

Partition List MEDIUM

Problem: Partition the list so all nodes less than x come before nodes >= x, preserving relative order. Return the head.

Remove Duplicates From Sorted List II MEDIUM

Problem: From a sorted list, delete every value that appears more than once (leaving only distinct values). Return the head.

Add Two Numbers MEDIUM

Problem: Two numbers are stored as linked lists with digits in reverse order. Add them and return the sum as a linked list.

Reorder List MEDIUM

Problem: Reorder the list from L0->L1->...->Ln into L0->Ln->L1->Ln-1->... Return the head.

Linked List Palindrome HARD

Find the middle, reverse the second half, compare. O(n) time, O(1) space.

class Solution:
    def is_palindrome_list(self, head):
        slow = fast = head
        while fast and fast.next:
            slow = slow.next; fast = fast.next.next
        prev = None                              # reverse second half
        while slow:
            slow.next, prev, slow = prev, slow, slow.next
        left, right = head, prev
        while right:
            if left.value != right.value: return False
            left = left.next; right = right.next
        return True

Zip Linked List HARD

1→2→3→4→5 becomes 1→5→2→4→3. Split, reverse the back half, interleave. O(n).

class Solution:
    def zip_linked_list(self, head):
        slow = fast = head
        while fast.next and fast.next.next:
            slow = slow.next; fast = fast.next.next
        second = slow.next; slow.next = None
        prev = None
        while second:
            second.next, prev, second = prev, second, second.next
        first, second = head, prev
        while second:
            f_next, s_next = first.next, second.next
            first.next = second; second.next = f_next
            first, second = f_next, s_next
        return head

Reverse Nodes in K-Group HARD

Problem: Reverse the nodes of the list k at a time; nodes that don't make a full group of k stay as-is. Return the head.
def reverse_in_k_groups(head, k):
    node = head
    count = 0
    while node and count < k:
        node = node.next
        count += 1
    if count < k:
        return head
    prev = reverse_in_k_groups(node, k)
    cur = head
    for _ in range(k):
        nxt = cur.next
        cur.next = prev
        prev = cur
        cur = nxt
    return prev

Merge K Sorted Linked Lists HARD

Problem: Merge k sorted linked lists into one sorted list using a min-heap of the current heads.

Sort a Linked List HARD

Problem: Sort the linked list in ascending order in O(n log n) time using merge sort.

Reverse a Sublist HARD

Problem: Reverse the nodes of the list from position left to position right (1-indexed) and return the head.

Remove Zero Sum Consecutive Nodes HARD

Problem: Repeatedly delete consecutive sequences of nodes that sum to zero. Return the head of the final list.

Split Linked List in Parts HARD

Problem: Split the list into k consecutive parts as equal in size as possible (earlier parts no smaller). Return the k parts.

Add Two Numbers II HARD

Problem: Two numbers are stored as linked lists with the most significant digit first. Add them and return the sum, most significant digit first.

Swapping Nodes in a Linked List HARD

Problem: Swap the values of the kth node from the beginning and the kth node from the end. Return the head.

Next Greater Node in Linked List HARD

Problem: For each node, find the value of the next node with a strictly greater value (0 if none). Return the answers as a list.

Plus One on a Linked List HARD

Problem: A non-negative number is stored as a linked list, most significant digit first. Add one and return the resulting list.

Stacks & Queues

Valid Parentheses EASY

Problem: Given a string of brackets ()[]{}, return True if every bracket is correctly opened and closed in order.
def valid_parentheses(s):
    pairs = {')': '(', ']': '[', '}': '{'}
    stack = []
    for c in s:
        if c in pairs:
            if not stack or stack.pop() != pairs[c]:
                return False
        else:
            stack.append(c)
    return not stack

Reverse a String Using a Stack EASY

Problem: Reverse the string by pushing each character onto a stack and popping them off.
def reverse_with_stack(s):
    stack = list(s)
    out = []
    while stack:
        out.append(stack.pop())
    return ''.join(out)

Baseball Game EASY

Problem: Process operations: an integer records a score, '+' records the sum of the last two, 'D' doubles the last, 'C' cancels the last. Return the total.
def baseball_game(ops):
    stack = []
    for op in ops:
        if op == '+':
            stack.append(stack[-1] + stack[-2])
        elif op == 'D':
            stack.append(stack[-1] * 2)
        elif op == 'C':
            stack.pop()
        else:
            stack.append(int(op))
    return sum(stack)

Remove All Adjacent Duplicates EASY

Problem: Repeatedly remove two adjacent equal characters until none remain. Return the final string.

Minimum Add to Make Parentheses Valid EASY

Problem: Return the minimum number of parentheses to insert so the string becomes valid.

Backspace String Compare EASY

Problem: '#' means a backspace. Return True if the two strings are equal after applying backspaces.

Make String Great EASY

Problem: Repeatedly remove adjacent pairs of the same letter in opposite case (like 'aA' or 'Bb'). Return the result.

Remove Outermost Parentheses EASY

Problem: Remove the outermost parentheses of every primitive group in the valid parentheses string. Return the result.

Maximum Nesting Depth of Parentheses EASY

Problem: Return the maximum nesting depth of the parentheses in the expression string.

Build an Array With Stack Operations EASY

Problem: Push integers 1,2,3,... and use 'Pop' to discard, to build exactly the target list. Return the sequence of operations.

Balanced Brackets MEDIUM

Are all brackets ()[]{} properly matched? Push opens, match on closes. O(n).

class Solution:
    def balanced_brackets(self, s):
        pairs = {")": "(", "]": "[", "}": "{"}
        stack = []
        for ch in s:
            if ch in "([{":
                stack.append(ch)
            elif ch in pairs:
                if not stack or stack.pop() != pairs[ch]:
                    return False
        return not stack

Sunset Views MEDIUM

Buildings that can see the sunset (taller than all buildings toward the direction). O(n).

class Solution:
    def sunset_views(self, buildings, direction):
        res, tallest = [], 0
        rng = range(len(buildings)) if direction == "WEST" else range(len(buildings)-1, -1, -1)
        for i in rng:
            if buildings[i] > tallest:
                res.append(i); tallest = buildings[i]
        return res if direction == "WEST" else res[::-1]

Next Greater Element MEDIUM

For each item, the next larger one to its right (wrapping around). Monotonic stack. O(n).

class Solution:
    def next_greater(self, arr):
        n = len(arr); res = [-1] * n; stack = []
        for i in range(2 * n):
            idx = i % n
            while stack and arr[stack[-1]] < arr[idx]:
                res[stack.pop()] = arr[idx]
            if i < n: stack.append(idx)
        return res

Reverse Polish Notation (evaluate) MEDIUM

Sort a Stack (recursively) MEDIUM

Min-Max Stack Construction MEDIUM

A stack that also returns its current min & max in O(1) (store them at each level).

Calendar Matching MEDIUM

Find free slots ≥ duration in two people's calendars. Merge busy blocks, return the gaps.

Next Greater Element II (Circular) MEDIUM

Problem: For each element in a circular array, find the next greater element scanning forward (wrapping around), or -1.

Daily Temperatures MEDIUM

Problem: For each day, return how many days you must wait for a warmer temperature (0 if none).

Evaluate Reverse Polish Notation MEDIUM

Problem: Evaluate the arithmetic expression given in Reverse Polish (postfix) notation. Division truncates toward zero.

Decode String MEDIUM

Problem: Decode strings like '3[a2[c]]' where k[...] means the bracketed part repeats k times. Return the expanded string.

Asteroid Collision MEDIUM

Problem: Asteroids move right (+) or left (-); equal sizes annihilate, otherwise the smaller explodes. Return the survivors.

Validate Stack Sequences MEDIUM

Problem: Given a push order and a pop order, return True if they could describe valid push/pop operations on one stack.

Simplify Absolute Path MEDIUM

Problem: Simplify a Unix-style absolute path (handling '.', '..', and repeated slashes). Return the canonical path.

Next Greater Element I MEDIUM

Problem: For each value in nums1 (a subset of nums2), find its next greater element to the right within nums2, or -1.

Score of Parentheses MEDIUM

Problem: () scores 1, AB scores A+B, and (A) scores 2*A. Return the total score of the balanced parentheses string.

Remove Invalid Parentheses (Minimal) MEDIUM

Problem: Remove the minimum number of parentheses so the result is valid, keeping all letters. Return one valid result.

Same BSTs (without building them) HARD

Do two arrays produce identical BSTs? Compare roots, then left/right subsets recursively. O(n²).

class Solution:
    def same_bsts(self, a, b):
        if len(a) != len(b): return False
        if not a: return True
        if a[0] != b[0]: return False
        left_a  = [x for x in a[1:] if x < a[0]]
        left_b  = [x for x in b[1:] if x < b[0]]
        right_a = [x for x in a[1:] if x >= a[0]]
        right_b = [x for x in b[1:] if x >= b[0]]
        return self.same_bsts(left_a, left_b) and self.same_bsts(right_a, right_b)

Largest Rectangle in Histogram HARD

Problem: Given bar heights, return the area of the largest rectangle that fits entirely under the histogram.
def largest_rectangle_stacks(heights):
    stack = []
    best = 0
    for i, h in enumerate(heights + [0]):
        while stack and heights[stack[-1]] >= h:
            height = heights[stack.pop()]
            width = i if not stack else i - stack[-1] - 1
            best = max(best, height * width)
        stack.append(i)
    return best

Maximal Rectangle HARD

Problem: Given a binary matrix, return the area of the largest rectangle containing only 1s.
def maximal_rectangle(matrix):
    if not matrix:
        return 0
    heights = [0] * len(matrix[0])
    best = 0
    for row in matrix:
        for i, v in enumerate(row):
            heights[i] = heights[i] + 1 if v == 1 else 0
        stack = []
        for i, h in enumerate(heights + [0]):
            while stack and heights[stack[-1]] >= h:
                height = heights[stack.pop()]
                width = i if not stack else i - stack[-1] - 1
                best = max(best, height * width)
            stack.append(i)
    return best

Trapping Rain Water (Stack) HARD

Problem: Given an elevation map, compute how much rain water it can trap, using a monotonic stack.

Basic Calculator HARD

Problem: Evaluate an expression containing non-negative integers, '+', '-', and parentheses.

Basic Calculator II HARD

Problem: Evaluate an expression with non-negative integers and the operators + - * / (integer division truncates toward zero), respecting precedence.

Remove Duplicate Letters HARD

Problem: Remove duplicate letters so every letter appears once and the result is the smallest in lexicographic order.

Sum of Subarray Minimums HARD

Problem: Return the sum of the minimum of every contiguous subarray, modulo 1e9+7, using a monotonic stack.

Longest Valid Parentheses HARD

Problem: Return the length of the longest substring of well-formed parentheses.

Exclusive Time of Functions HARD

Problem: Given start/end logs of nested function calls on a single thread, return the exclusive running time of each function.

132 Pattern HARD

Problem: Return True if there exist indices i

Trees & BST

Find Closest Value In BST EASY

class Solution:
    def find_closest(self, root, target):
        closest = root.value; node = root
        while node:
            if abs(target - node.value) < abs(target - closest):
                closest = node.value
            node = node.left if target < node.value else node.right
        return closest

Evaluate Expression Tree EASY

Leaves are numbers (≥0); internal nodes are operators (−1 add, −2 subtract, −3 divide, −4 multiply).

class Solution:
    def evaluate_expression_tree(self, node):
        if node.value >= 0: return node.value
        left = self.evaluate_expression_tree(node.left)
        right = self.evaluate_expression_tree(node.right)
        if node.value == -1: return left + right
        if node.value == -2: return left - right
        if node.value == -3: return int(left / right)
        return left * right

Maximum Depth of Binary Tree EASY

Problem: Return the maximum depth (number of nodes along the longest root-to-leaf path) of a binary tree.
def max_depth_trees(root):
    if not root:
        return 0
    return 1 + max(max_depth_trees(root.left), max_depth_trees(root.right))

Minimum Depth of Binary Tree EASY

Problem: Return the minimum depth: the number of nodes along the shortest path from the root to a leaf.

Count Nodes in a Binary Tree EASY

Problem: Return the total number of nodes in the tree.

Sum of All Nodes EASY

Problem: Return the sum of all node values in the tree.

Invert a Binary Tree EASY

Problem: Swap the left and right child of every node (mirror the tree) and return the root.

Same Tree EASY

Problem: Return True if two binary trees are structurally identical and have the same node values.

Maximum Value in a Binary Tree EASY

Problem: Return the largest value stored anywhere in the tree.

Count Leaf Nodes EASY

Problem: Return the number of leaf nodes (nodes with no children) in the tree.

Search in a Binary Search Tree EASY

Problem: Return True if the value exists in the binary search tree, using the BST ordering to guide the search.

Range Sum of BST EASY

Problem: Return the sum of all node values in the BST that fall within the inclusive range [low, high].

Tree Traversal — BFS & DFS MEDIUM

Problem: visit every node in a binary tree.

DFS (depth-first) uses recursion / a stack; BFS (breadth-first, level by level) uses a queue.

def dfs(node):                # depth-first (pre-order)
    if node is None:
        return
    print(node.value)
    dfs(node.left)
    dfs(node.right)

from collections import deque
def bfs(root):                # breadth-first (level order)
    queue = deque([root])
    while queue:
        node = queue.popleft()
        print(node.value)
        if node.left:  queue.append(node.left)
        if node.right: queue.append(node.right)

Validate BST MEDIUM

class Solution:
    def validate_bst(self, node, lo=float("-inf"), hi=float("inf")):
        if node is None: return True
        if not (lo < node.value < hi): return False
        return (self.validate_bst(node.left, lo, node.value) and
                self.validate_bst(node.right, node.value, hi))

Invert Binary Tree MEDIUM

class Solution:
    def invert_tree(self, node):
        if node is None: return
        node.left, node.right = node.right, node.left
        self.invert_tree(node.left)
        self.invert_tree(node.right)

BST Traversal (in / pre / post order) MEDIUM

Youngest Common Ancestor (LCA) MEDIUM

Lowest common ancestor when nodes have a .parent. Equalize depths, then climb together. O(d).

Iterative In-order Traversal MEDIUM

Symmetrical Tree MEDIUM

Height Balanced Binary Tree MEDIUM

Flatten Binary Tree (to a list) MEDIUM

Min Height BST MEDIUM

Build a balanced BST from a sorted array — recurse on the middle. O(n).

Find Kth Largest Value In BST MEDIUM

Reverse in-order (right, node, left) gives values largest-first. O(h+k).

Reconstruct BST (from pre-order) MEDIUM

Find Successor (in-order) MEDIUM

Merge Binary Trees MEDIUM

Max Path Sum In Binary Tree HARD

Largest sum along any path. At each node, best = node + best-left-branch + best-right-branch. O(n).

class Solution:
    def max_path_sum(self, root):
        best = [float("-inf")]
        def helper(node):
            if not node: return 0
            left = max(helper(node.left), 0)
            right = max(helper(node.right), 0)
            best[0] = max(best[0], node.value + left + right)
            return node.value + max(left, right)
        helper(root)
        return best[0]

All Kinds Of Node Depths HARD

Sum of node depths across every subtree. O(n) with a helper that returns sum + count.

class Solution:
    def all_kinds_of_node_depths(self, root):
        def helper(node):
            if not node: return (0, 0)          # (sum_of_depths, node_count)
            ls, lc = helper(node.left)
            rs, rc = helper(node.right)
            depth_sum = ls + lc + rs + rc        # +1 depth for each descendant
            return (depth_sum, lc + rc + 1)
        def total(node):
            if not node: return 0
            return helper(node)[0] + total(node.left) + total(node.right)
        return total(root)

Number Of Binary Tree Topologies HARD

How many tree shapes with n nodes (the Catalan numbers). DP. O(n²).

class Solution:
    def number_of_binary_tree_topologies(self, n):
        cache = [1]
        for m in range(1, n + 1):
            total = 0
            for left in range(m):
                total += cache[left] * cache[m - 1 - left]
            cache.append(total)
        return cache[n]

Compare Leaf Traversal HARD

Do two trees have the same left-to-right leaf sequence?

Find Nodes Distance K HARD

All nodes exactly k edges from a target. Map parents, then BFS treating the tree as a graph. O(n).

Binary Tree Maximum Path Sum HARD

Problem: A path may start and end at any nodes and goes through parent-child connections. Return the maximum sum of any such path.

Lowest Common Ancestor HARD

Problem: Given the values of two nodes in a binary tree, return the value of their lowest common ancestor.

Path Sum III (Count Paths) HARD

Problem: Count the number of downward paths (any node to any descendant) whose values sum to the target, using prefix sums.

Vertical Order Traversal HARD

Problem: Return the node values grouped by column (left to right). Within a column, order by row, and by value on ties.

Maximum Width of Binary Tree HARD

Problem: Return the maximum width of the tree: the longest distance between the leftmost and rightmost non-null nodes on any level (counting the null gaps between them).

Distribute Coins in Binary Tree HARD

Problem: Each node has some coins; there are exactly as many coins as nodes. In one move you may pass a coin between adjacent nodes. Return the minimum moves to give every node exactly one coin.

Graphs

Build an Adjacency List EASY

Problem: Given n nodes (0..n-1) and a list of undirected edges, build and return an adjacency list (a list of neighbor lists).
def build_adjacency_list(n, edges):
    adj = [[] for _ in range(n)]
    for u, v in edges:
        adj[u].append(v)
        adj[v].append(u)
    return adj

Node Degree EASY

Problem: Return the degree (number of neighbors) of a node in an adjacency list.
def node_degree(adj, node):
    return len(adj[node])

Count Edges in an Undirected Graph EASY

Problem: Given an adjacency list of an undirected graph, return the number of distinct edges.
def count_edges(adj):
    total = sum(len(neighbors) for neighbors in adj)
    return total // 2

Check if an Edge Exists EASY

Problem: Return True if there is a direct edge from u to v in the adjacency list.

Breadth-First Search Order EASY

Problem: Return the order in which nodes are visited by BFS starting from the given node.

Depth-First Search Order EASY

Problem: Return the order in which nodes are visited by DFS starting from the given node.

Count Reachable Nodes EASY

Problem: Return how many nodes are reachable from the start node (including itself).

List a Node's Neighbors EASY

Problem: Return the sorted list of neighbors of a node in an adjacency list.

Path Exists Between Two Nodes EASY

Problem: Return True if there is a path from source to destination in an undirected graph given by an adjacency list.

Count Connected Components EASY

Problem: Given n nodes and a list of undirected edges, return the number of connected components.

Cycle In Graph MEDIUM

Detect a cycle in a directed graph (adjacency list). DFS tracking the current path. O(V+E).

class Solution:
    def cycle_in_graph(self, edges):
        n = len(edges)
        visited = [False] * n; in_path = [False] * n
        def dfs(node):
            visited[node] = in_path[node] = True
            for nb in edges[node]:
                if not visited[nb]:
                    if dfs(nb): return True
                elif in_path[nb]:
                    return True
            in_path[node] = False
            return False
        return any(dfs(i) for i in range(n) if not visited[i])

Remove Islands MEDIUM

Flip any group of 1s not connected to the border to 0. Mark border-connected 1s, then clear the rest. O(w·h).

class Solution:
    def remove_islands(self, matrix):
        rows, cols = len(matrix), len(matrix[0])
        def fill(r, c):
            stack = [(r, c)]
            while stack:
                r, c = stack.pop()
                if 0 <= r < rows and 0 <= c < cols and matrix[r][c] == 1:
                    matrix[r][c] = 2                      # mark as safe
                    stack += [(r+1,c),(r-1,c),(r,c+1),(r,c-1)]
        for r in range(rows):
            for c in range(cols):
                if (r in (0, rows-1) or c in (0, cols-1)) and matrix[r][c] == 1:
                    fill(r, c)
        for r in range(rows):
            for c in range(cols):
                matrix[r][c] = 1 if matrix[r][c] == 2 else 0
        return matrix

River Sizes MEDIUM

Sizes of every connected group of 1s in a grid. Flood-fill each. O(w·h).

class Solution:
    def river_sizes(self, matrix):
        sizes = []
        visited = [[False] * len(matrix[0]) for _ in matrix]
        for r in range(len(matrix)):
            for c in range(len(matrix[0])):
                if matrix[r][c] == 1 and not visited[r][c]:
                    size = 0; stack = [(r, c)]
                    while stack:
                        i, j = stack.pop()
                        if (i < 0 or j < 0 or i >= len(matrix) or j >= len(matrix[0])
                                or visited[i][j] or matrix[i][j] == 0):
                            continue
                        visited[i][j] = True; size += 1
                        stack += [(i+1,j), (i-1,j), (i,j+1), (i,j-1)]
                    sizes.append(size)
        return sizes

Union-Find (Disjoint Set) MEDIUM

Track which items are connected. Near-O(1) with path compression.

Two-Colorable (bipartite check) MEDIUM

Can the graph be 2-colored so no edge joins same colors? BFS, alternate colors. O(V+E).

Min Knight Moves (BFS) MEDIUM

Number of Islands MEDIUM

Problem: Given a grid of '1' (land) and '0' (water), return the number of islands (groups of land connected horizontally or vertically).

Max Area of Island MEDIUM

Problem: Return the size (in cells) of the largest island in the grid.

Flood Fill MEDIUM

Problem: Starting from pixel (sr, sc), replace the color of that region (connected same-colored pixels) with new_color. Return the image.

Is Graph Bipartite MEDIUM

Problem: Given an adjacency list, return True if the graph can be 2-colored so no edge connects two nodes of the same color.

Course Schedule (Can Finish) MEDIUM

Problem: Given numCourses and prerequisite pairs [a, b] (take b before a), return True if all courses can be finished (no cycle).

Topological Sort HARD

Order tasks so each comes after its prerequisites. Kahn's algorithm (in-degrees + queue). O(V+E).

from collections import deque

class Solution:
    def topological_sort(self, jobs, deps):
        graph = {j: [] for j in jobs}
        indegree = {j: 0 for j in jobs}
        for a, b in deps:                 # a must come before b
            graph[a].append(b); indegree[b] += 1
        queue = deque(j for j in jobs if indegree[j] == 0)
        order = []
        while queue:
            j = queue.popleft(); order.append(j)
            for nb in graph[j]:
                indegree[nb] -= 1
                if indegree[nb] == 0: queue.append(nb)
        return order if len(order) == len(jobs) else []   # [] means a cycle

Dijkstra's Algorithm (shortest paths) HARD

Shortest distance from a start node to all others (non-negative weights). Min-heap. O(E log V).

import heapq

class Solution:
    def dijkstra(self, start, edges):
        # edges[i] = list of [destination, weight]
        dist = [float("inf")] * len(edges); dist[start] = 0
        pq = [(0, start)]
        while pq:
            d, node = heapq.heappop(pq)
            if d > dist[node]: continue
            for nb, w in edges[node]:
                if d + w < dist[nb]:
                    dist[nb] = d + w; heapq.heappush(pq, (d + w, nb))
        return [-1 if d == float("inf") else d for d in dist]

Boggle Board HARD

Find which words appear on the board (8-directional). Trie of words + DFS.

class Solution:
    def boggle_board(self, board, words):
        trie = {}
        for w in words:                 # build a trie
            node = trie
            for ch in w: node = node.setdefault(ch, {})
            node["*"] = w
        rows, cols = len(board), len(board[0])
        found = set()
        def dfs(r, c, node, visited):
            if (r < 0 or c < 0 or r >= rows or c >= cols or (r, c) in visited
                    or board[r][c] not in node):
                return
            node = node[board[r][c]]; visited = visited | {(r, c)}
            if "*" in node: found.add(node["*"])
            for dr in (-1, 0, 1):
                for dc in (-1, 0, 1):
                    dfs(r + dr, c + dc, node, visited)
        for r in range(rows):
            for c in range(cols):
                dfs(r, c, trie, set())
        return list(found)

A* Algorithm (heuristic pathfinding) HARD

Like Dijkstra but guided by a heuristic toward the goal. Min-heap on (cost + estimate).

Detect Arbitrage HARD

Is there a currency cycle that multiplies to > 1? Take −log of rates → a profitable cycle is a negative cycle (Bellman-Ford). O(n³).

Kruskal's Algorithm (MST) HARD

Cheapest set of edges connecting every node. Sort edges, add if they join two different groups (union-find). O(E log E).

Prim's Algorithm (MST) HARD

Course Schedule II (Order) HARD

Problem: Return a valid ordering of courses to take all of them, or an empty list if it is impossible (there is a cycle).

Network Delay Time HARD

Problem: Given directed weighted edges [u, v, w], n nodes (1-indexed), and a source k, return the time for all nodes to receive a signal, or -1 if some are unreachable.

Word Ladder Length HARD

Problem: Return the number of words in the shortest transformation sequence from begin_word to end_word, changing one letter at a time (each intermediate word must be in the word list), or 0 if impossible.

Cheapest Flights Within K Stops HARD

Problem: Given flights [from, to, price], find the cheapest price from src to dst using at most k stops, or -1 if there is no such route (Bellman-Ford).

Heaps

Kth Largest Element in an Array EASY

Problem: Return the kth largest element in an unsorted array (1-indexed, k=1 means the maximum).
def kth_largest_element(nums, k):
    import heapq
    return heapq.nlargest(k, nums)[-1]

Kth Smallest Element in an Array EASY

Problem: Return the kth smallest element in an unsorted array (1-indexed).
def kth_smallest_element(nums, k):
    import heapq
    return heapq.nsmallest(k, nums)[-1]

K Smallest Elements EASY

Problem: Return the k smallest elements of the array, sorted ascending.
def k_smallest(nums, k):
    import heapq
    return sorted(heapq.nsmallest(k, nums))

K Largest Elements EASY

Problem: Return the k largest elements of the array, sorted descending.

Last Stone Weight EASY

Problem: Repeatedly smash the two heaviest stones; if unequal, the difference returns to the pile. Return the weight of the last stone (0 if none).

Heap Sort EASY

Problem: Sort the array ascending using a heap (push all, then pop the minimum repeatedly).

Is Array a Valid Min-Heap EASY

Problem: An array is a min-heap if every parent is <= its children. Return True or False.

Sum of K Smallest Elements EASY

Problem: Return the sum of the k smallest elements in the array.

Sum of K Largest Elements EASY

Problem: Return the sum of the k largest elements in the array.

Minimum Cost to Connect Ropes EASY

Problem: Connecting two ropes costs the sum of their lengths. Return the minimum total cost to connect all ropes into one.

Top K Frequent Elements MEDIUM

Problem: Return the k most frequent elements (any order), using a heap over the frequency counts.
def top_k_frequent(nums, k):
    import heapq
    from collections import Counter
    freq = Counter(nums)
    return heapq.nlargest(k, freq.keys(), key=freq.get)

K Closest Points to Origin MEDIUM

Problem: Return the k points closest to the origin (0,0), ordered by increasing distance.
def k_closest_points(points, k):
    import heapq
    return heapq.nsmallest(k, points, key=lambda p: p[0]**2 + p[1]**2)

Kth Largest in a Stream MEDIUM

Problem: Given an initial array and a stream of added values, return the kth largest element after each addition.
def kth_largest_stream(k, initial, adds):
    import heapq
    heap = initial[:]
    heapq.heapify(heap)
    while len(heap) > k:
        heapq.heappop(heap)
    out = []
    for x in adds:
        heapq.heappush(heap, x)
        if len(heap) > k:
            heapq.heappop(heap)
        out.append(heap[0])
    return out

Sort Characters by Frequency MEDIUM

Problem: Return the string with characters sorted by decreasing frequency (ties broken by heap order).

Find K Pairs With Smallest Sums MEDIUM

Problem: Given two sorted arrays, return the k pairs (a,b) with the smallest sums a+b.

Minimum Number of Meeting Rooms MEDIUM

Problem: Given meeting intervals, return the minimum number of rooms needed so no two overlapping meetings share a room.

Furthest Building You Can Reach MEDIUM

Problem: Climbing up needs either a ladder or that many bricks. Use ladders on the biggest climbs. Return the furthest building index reachable.

Reduce Array Size to Half MEDIUM

Problem: Remove all occurrences of chosen values. Return the minimum number of distinct values to remove so at least half the array is gone.

Maximum Score After K Operations MEDIUM

Problem: In each operation, take the largest element x, add it to your score, and replace it with ceil(x/3). Return the max score after k operations.

Take Gifts With Maximum Value MEDIUM

Problem: Each second, take the pile with the most gifts and leave floor(sqrt(pile)) behind. Return the total gifts remaining after k seconds.

Continuous Median HARD

Median of a growing stream. Keep a max-heap of the low half & a min-heap of the high half. O(log n) per add.

import heapq
class ContinuousMedian:
    def __init__(self):
        self.lo = []   # max-heap (store negatives)
        self.hi = []   # min-heap
    def add(self, num):
        heapq.heappush(self.lo, -num)
        heapq.heappush(self.hi, -heapq.heappop(self.lo))  # balance
        if len(self.hi) > len(self.lo):
            heapq.heappush(self.lo, -heapq.heappop(self.hi))
    def median(self):
        if len(self.lo) > len(self.hi): return -self.lo[0]
        return (-self.lo[0] + self.hi[0]) / 2

Heap Sort HARD

import heapq

class Solution:
    def heap_sort(self, arr):
        heapq.heapify(arr)                       # O(n)
        return [heapq.heappop(arr) for _ in range(len(arr))]   # n × O(log n)

Median Of Two Sorted Arrays HARD

O(log(min(m,n))) by binary-searching the partition point.

class Solution:
    def median_two_sorted(self, a, b):
        if len(a) > len(b): a, b = b, a
        m, n = len(a), len(b)
        lo, hi = 0, m
        while lo <= hi:
            i = (lo + hi) // 2
            j = (m + n + 1) // 2 - i
            a_l = a[i-1] if i > 0 else float("-inf")
            a_r = a[i]   if i < m else float("inf")
            b_l = b[j-1] if j > 0 else float("-inf")
            b_r = b[j]   if j < n else float("inf")
            if a_l <= b_r and b_l <= a_r:
                if (m + n) % 2: return max(a_l, b_l)
                return (max(a_l, b_l) + min(a_r, b_r)) / 2
            elif a_l > b_r: hi = i - 1
            else: lo = i + 1

Find Median From a Data Stream HARD

Problem: Return the running median after each number arrives, maintained with a max-heap (low half) and min-heap (high half).

Merge K Sorted Lists HARD

Problem: Merge k already-sorted lists into one sorted list using a min-heap of the current heads.

Kth Smallest Element in a Sorted Matrix HARD

Problem: Each row and column is sorted ascending. Return the kth smallest value using a heap of row heads.

Smallest Range Covering K Lists HARD

Problem: Given k sorted lists, return the smallest range [a,b] that includes at least one number from each list.

Sliding Window Median HARD

Problem: Return the median of every contiguous window of size k as it slides across the array.

Minimum Cost to Hire K Workers HARD

Problem: Each worker has quality and a minimum wage expectation. Pay must be proportional to quality and meet each worker's minimum. Return the minimum cost to hire exactly k workers.

Single-Threaded CPU HARD

Problem: Tasks are [enqueue_time, processing_time]. The CPU always picks the available task with the shortest processing time (ties by index). Return the processing order.

Maximum Performance of a Team HARD

Problem: A team's performance is (sum of its members' speeds) x (minimum efficiency among them). Choose at most k engineers to maximize performance, modulo 1e9+7.

Minimize Deviation in Array HARD

Problem: You may double any odd number and halve any even number, any number of times. Return the minimum possible difference between the largest and smallest elements.

Rearrange String K Distance Apart HARD

Problem: Rearrange the string so identical characters are at least k apart. Return a valid arrangement, or '' if impossible.

Recursion & Backtracking

Factorial (Recursive) EASY

Problem: Compute n! recursively (0! = 1).
def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

Fibonacci Number EASY

Problem: Return the nth Fibonacci number (fib(0)=0, fib(1)=1) using memoized recursion.
def fibonacci(n, memo=None):
    if memo is None:
        memo = {}
    if n < 2:
        return n
    if n in memo:
        return memo[n]
    memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo)
    return memo[n]

Sum From 1 to N (Recursive) EASY

Problem: Return the sum 1 + 2 + ... + n using recursion.
def sum_to_n(n):
    if n <= 0:
        return 0
    return n + sum_to_n(n - 1)

Power Function (Recursive) EASY

Problem: Compute base raised to a non-negative integer exponent using recursion.

Reverse a String Recursively EASY

Problem: Reverse a string using recursion (no slicing tricks in the base logic).

Greatest Common Divisor EASY

Problem: Compute gcd(a, b) using the recursive Euclidean algorithm.

Count Digits (Recursive) EASY

Problem: Count how many digits are in a non-negative integer using recursion.

Sum of Digits (Recursive) EASY

Problem: Return the sum of the digits of a non-negative integer using recursion.

Recursive Palindrome Check EASY

Problem: Return True if the string is a palindrome, checked recursively.

Sum of an Array (Recursive) EASY

Problem: Return the sum of a list of numbers using recursion.

Permutations MEDIUM

class Solution:
    def permutations(self, arr):
        if len(arr) <= 1: return [arr[:]]
        res = []
        for i in range(len(arr)):
            rest = arr[:i] + arr[i+1:]
            for p in self.permutations(rest):
                res.append([arr[i]] + p)
        return res

Powerset (all subsets) MEDIUM

class Solution:
    def powerset(self, arr):
        subsets = [[]]
        for n in arr:
            subsets += [s + [n] for s in subsets]
        return subsets
    # [1,2] -> [[], [1], [2], [1,2]]

Phone Number Mnemonics MEDIUM

class Solution:
    def phone_mnemonics(self, digits):
        keys = {"2":"abc","3":"def","4":"ghi","5":"jkl","6":"mno",
                "7":"pqrs","8":"tuv","9":"wxyz","0":"0","1":"1"}
        res = []
        def backtrack(i, cur):
            if i == len(digits):
                res.append("".join(cur)); return
            for ch in keys[digits[i]]:
                cur.append(ch); backtrack(i+1, cur); cur.pop()
        backtrack(0, [])
        return res

Staircase Traversal MEDIUM

Ways to climb height stairs taking 1..maxSteps at a time. DP. O(n·k).

Generate Div Tags (balanced) MEDIUM

All valid arrangements of n <div></div> pairs (same idea as "generate parentheses").

Subsets MEDIUM

Problem: Return all possible subsets (the power set) of a list of distinct integers.

Permutations MEDIUM

Problem: Return all permutations of a list of distinct integers.

Combinations MEDIUM

Problem: Return all combinations of k numbers chosen from the range 1..n.

Combination Sum MEDIUM

Problem: Given distinct candidates and a target, return all unique combinations that sum to target. Each candidate may be reused.

Generate Parentheses MEDIUM

Problem: Given n pairs of parentheses, generate all combinations of well-formed parentheses.

Letter Combinations of a Phone Number MEDIUM

Problem: Given digits 2-9, return all letter combinations the number could spell (like on a phone keypad).

Subsets II (With Duplicates) MEDIUM

Problem: Return all unique subsets of a list that may contain duplicate integers.

Permutations II (With Duplicates) MEDIUM

Problem: Return all unique permutations of a list that may contain duplicate integers.

Combination Sum II MEDIUM

Problem: Given candidates (possibly with duplicates) and a target, return all unique combinations summing to target. Each number is used at most once.

Restore IP Addresses MEDIUM

Problem: Given a string of digits, return all valid IP addresses that can be formed by inserting dots (each part 0-255, no leading zeros).

Solve Sudoku HARD

Fill the grid by trying digits and backtracking when stuck. 0 = empty.

class Solution:
    def solve_sudoku(self, board):
        def valid(r, c, val):
            for i in range(9):
                if board[r][i] == val or board[i][c] == val: return False
            br, bc = 3 * (r // 3), 3 * (c // 3)
            for i in range(br, br + 3):
                for j in range(bc, bc + 3):
                    if board[i][j] == val: return False
            return True
        def solve():
            for r in range(9):
                for c in range(9):
                    if board[r][c] == 0:
                        for val in range(1, 10):
                            if valid(r, c, val):
                                board[r][c] = val
                                if solve(): return True
                                board[r][c] = 0      # backtrack
                        return False
            return True
        solve()
        return board

Count solutions HARD

Place N queens so none attack each other. Backtrack column by column, tracking used columns & diagonals.

class Solution:
    def non_attacking_queens(self, n):
        cols = set(); diag1 = set(); diag2 = set()
        def place(row):
            if row == n: return 1
            count = 0
            for col in range(n):
                if col in cols or (row+col) in diag1 or (row-col) in diag2:
                    continue
                cols.add(col); diag1.add(row+col); diag2.add(row-col)
                count += place(row + 1)
                cols.discard(col); diag1.discard(row+col); diag2.discard(row-col)
            return count
        return place(0)

N-Queens (Count Solutions) HARD

Problem: Return the number of distinct ways to place n queens on an n x n board so none attack each other.
def total_n_queens_recursion(n):
    cols = set()
    diag1 = set()
    diag2 = set()
    def backtrack(row):
        if row == n:
            return 1
        count = 0
        for col in range(n):
            if col in cols or (row - col) in diag1 or (row + col) in diag2:
                continue
            cols.add(col); diag1.add(row - col); diag2.add(row + col)
            count += backtrack(row + 1)
            cols.remove(col); diag1.remove(row - col); diag2.remove(row + col)
        return count
    return backtrack(0)

Word Search HARD

Problem: Given a grid of letters, return True if the word can be spelled by moving to adjacent cells (up/down/left/right) without reusing a cell.

Palindrome Partitioning HARD

Problem: Partition the string so every substring is a palindrome. Return all possible partitionings.

Combination Sum III HARD

Problem: Find all combinations of k distinct numbers from 1..9 that sum to n (each number used at most once).

Permutation Sequence HARD

Problem: Return the kth permutation (1-indexed) of the numbers 1..n in lexicographic order.

Gray Code HARD

Problem: Return an n-bit gray code sequence: a list of 2^n integers where consecutive values (and the last and first) differ by exactly one bit.

Beautiful Arrangement HARD

Problem: Count the permutations of 1..n where for every position i (1-indexed), either the value is divisible by i or i is divisible by the value.

Partition to K Equal Sum Subsets HARD

Problem: Return True if the array can be partitioned into k non-empty subsets that all have the same sum.

Matchsticks to Square HARD

Problem: Given matchstick lengths, return True if they can all be used to form the four equal sides of a square.

Letter Case Permutation HARD

Problem: Given a string of letters and digits, return all strings formed by toggling the case of each letter in every possible way.

Dynamic Programming

Climbing Stairs EASY

Problem: You can climb 1 or 2 steps at a time. Return the number of distinct ways to reach the top of n stairs.
def climbing_stairs(n):
    if n <= 2:
        return n
    a, b = 1, 2
    for _ in range(3, n + 1):
        a, b = b, a + b
    return b

Fibonacci Number (Bottom-Up) EASY

Problem: Return the nth Fibonacci number using bottom-up dynamic programming (fib(0)=0, fib(1)=1).
def fib_dp(n):
    if n < 2:
        return n
    a, b = 0, 1
    for _ in range(2, n + 1):
        a, b = b, a + b
    return b

N-th Tribonacci Number EASY

Problem: The Tribonacci sequence starts 0, 1, 1 and each term is the sum of the previous three. Return the nth term.
def tribonacci(n):
    if n == 0:
        return 0
    if n <= 2:
        return 1
    a, b, c = 0, 1, 1
    for _ in range(3, n + 1):
        a, b, c = b, c, a + b + c
    return c

Min Cost Climbing Stairs EASY

Problem: Each stair has a cost to step on. You may start at index 0 or 1 and climb 1 or 2 steps. Return the minimum cost to reach the top (past the last stair).

House Robber EASY

Problem: Given house values along a street, return the maximum you can rob without robbing two adjacent houses.

Is Subsequence EASY

Problem: Return True if s is a subsequence of t (its characters appear in order within t).

Pascal's Triangle Row EASY

Problem: Return the row at the given 0-based index of Pascal's triangle.

Unique Paths EASY

Problem: A robot moves only right or down on an m x n grid from the top-left to the bottom-right. Return the number of unique paths.

Minimum Path Sum EASY

Problem: Given a grid of non-negative numbers, return the minimum sum along a path from the top-left to the bottom-right, moving only right or down.

Maximum Subarray (DP) EASY

Problem: Return the largest sum of any contiguous subarray using Kadane's dynamic programming.

Dynamic Programming — Fibonacci MEDIUM

Problem: the nth Fibonacci number — fast.

Pattern: naive recursion is O(2ⁿ). Memoize (cache) results to make it O(n).

def fib(n, memo={}):
    if n <= 1:
        return n
    if n in memo:
        return memo[n]
    memo[n] = fib(n - 1, memo) + fib(n - 2, memo)
    return memo[n]

Min Number Of Coins For Change MEDIUM

class Solution:
    def min_coins(self, n, denoms):
        dp = [float("inf")] * (n + 1)
        dp[0] = 0
        for coin in denoms:
            for amount in range(coin, n + 1):
                dp[amount] = min(dp[amount], dp[amount - coin] + 1)
        return dp[n] if dp[n] != float("inf") else -1

Number Of Ways To Make Change MEDIUM

class Solution:
    def ways_to_make_change(self, n, denoms):
        dp = [0] * (n + 1)
        dp[0] = 1
        for coin in denoms:
            for amount in range(coin, n + 1):
                dp[amount] += dp[amount - coin]
        return dp[n]

Max Subset Sum No Adjacent MEDIUM

Levenshtein Distance (edit distance) MEDIUM

Max Sum Increasing Subsequence MEDIUM

Number Of Ways To Traverse Graph (grid) MEDIUM

Paths from top-left to bottom-right moving only right/down. O(w·h).

Coin Change (Number of Combinations) MEDIUM

Problem: Given coin denominations and a target amount, return the number of distinct combinations that make up the amount.

Word Break MEDIUM

Problem: Return True if the string can be segmented into a space-separated sequence of words from the given dictionary.

Decode Ways MEDIUM

Problem: A message of digits is decoded with 'A'->1 ... 'Z'->26. Return the number of ways to decode the string.

Longest Palindromic Substring MEDIUM

Problem: Return the longest contiguous substring of s that is a palindrome (expand around each center).

Numbers In Pi HARD

Fewest spaces to break a digit string into "known" numbers. Memoized recursion. O(n³).

class Solution:
    def numbers_in_pi(self, pi, numbers):
        known = set(numbers); cache = {}
        def helper(idx):
            if idx == len(pi): return -1          # -1 cancels the last +1
            if idx in cache: return cache[idx]
            best = float("inf")
            for i in range(idx, len(pi)):
                if pi[idx:i+1] in known:
                    best = min(best, 1 + helper(i + 1))
            cache[idx] = best
            return best
        result = helper(0)
        return -1 if result == float("inf") else result

Max Profit With K Transactions (stocks) HARD

class Solution:
    def max_profit_k(self, prices, k):
        if not prices: return 0
        dp = [0] * len(prices)
        for _ in range(k):
            max_diff = -prices[0]; new = [0] * len(prices)
            for d in range(1, len(prices)):
                new[d] = max(new[d-1], prices[d] + max_diff)
                max_diff = max(max_diff, dp[d] - prices[d])
            dp = new
        return dp[-1]

Dice Throws (ways to reach a target) HARD

class Solution:
    def dice_throws(self, num_dice, num_sides, target):
        dp = [[0] * (target + 1) for _ in range(num_dice + 1)]
        dp[0][0] = 1
        for d in range(1, num_dice + 1):
            for t in range(1, target + 1):
                for s in range(1, min(t, num_sides) + 1):
                    dp[d][t] += dp[d-1][t-s]
        return dp[num_dice][target]

Disk Stacking HARD

Tallest stack of disks where each must be strictly smaller in all 3 dimensions. DP after sorting by height. O(n²).

Interweaving Strings HARD

Is three an interleaving of one and two (keeping each one's order)? Memoized recursion. O(n·m).

Longest String Chain HARD

Longest chain where each word becomes the next by adding one letter. Sort by length, DP. O(n·L²).

Palindrome Partitioning Min Cuts HARD

Fewest cuts so every piece is a palindrome. Precompute palindromes, then DP. O(n²).

Longest Common Subsequence HARD

Longest Increasing Subsequence HARD

0/1 Knapsack HARD

Maximize value within a weight capacity. Classic 2-D DP. O(n·capacity).

Greedy

Array Partition (Max Sum of Min Pairs) EASY

Problem: Split 2n integers into n pairs so the sum of the smaller value in each pair is as large as possible. Return that sum.
def array_pair_sum(nums):
    nums.sort()
    return sum(nums[::2])

Maximum Units on a Truck EASY

Problem: Each box type is [count, units_per_box]. Load at most truck_size boxes to maximize total units.
def maximum_units(boxes, truck_size):
    boxes.sort(key=lambda b: -b[1])
    total = 0
    for count, units in boxes:
        take = min(count, truck_size)
        total += take * units
        truck_size -= take
        if truck_size == 0:
            break
    return total

Largest Perimeter Triangle EASY

Problem: Return the largest perimeter of a triangle with three of these side lengths, or 0 if impossible.
def largest_perimeter(nums):
    nums.sort(reverse=True)
    for i in range(len(nums) - 2):
        if nums[i] < nums[i + 1] + nums[i + 2]:
            return nums[i] + nums[i + 1] + nums[i + 2]
    return 0

Can Place Flowers EASY

Problem: A flowerbed (0=empty, 1=planted) allows no two adjacent flowers. Return True if you can plant n more.

Lemonade Change EASY

Problem: Customers pay with 5, 10, or 20 bills for a 5-dollar lemonade. Return True if you can give correct change to everyone in order.

Distribute Candies EASY

Problem: Given candies labeled by type, a sister may eat only half of them. Return the maximum number of distinct types she can keep.

Best Time to Buy and Sell Stock II EASY

Problem: You may buy and sell as many times as you like. Return the maximum total profit from the price series.

Assign Cookies EASY

Problem: Each child i needs a cookie of size >= greed[i]. Match cookies to children to maximize the number of content children.

Maximize Sum After K Negations EASY

Problem: You may negate any element up to k times (an element can be negated more than once). Maximize the array's sum.

Split a String in Balanced Strings EASY

Problem: A balanced string has equal numbers of 'L' and 'R'. Return the maximum number of balanced pieces you can split s into.

Class Photos / Tandem Bicycle / Non-Constructible Change

Jump Game MEDIUM

Problem: Each value is your maximum jump length from that index. Return True if you can reach the last index.
def can_jump_greedy(nums):
    reach = 0
    for i, n in enumerate(nums):
        if i > reach:
            return False
        reach = max(reach, i + n)
    return True

Jump Game II MEDIUM

Problem: Each value is your maximum jump length. Return the minimum number of jumps to reach the last index.
def jump_greedy(nums):
    jumps = cur_end = farthest = 0
    for i in range(len(nums) - 1):
        farthest = max(farthest, i + nums[i])
        if i == cur_end:
            jumps += 1
            cur_end = farthest
    return jumps

Gas Station MEDIUM

Problem: gas[i] fuel is available at station i and it costs cost[i] to reach the next. Return the start index of a full circular trip, or -1.
def can_complete_circuit_greedy(gas, cost):
    if sum(gas) < sum(cost):
        return -1
    total = start = 0
    for i in range(len(gas)):
        total += gas[i] - cost[i]
        if total < 0:
            total = 0
            start = i + 1
    return start

Task Scheduler MEDIUM

Problem: Given task labels and a cooldown n between identical tasks, return the least total time (including idles) to finish all tasks.

Partition Labels MEDIUM

Problem: Partition the string into as many parts as possible so each letter appears in at most one part. Return the part sizes.

Non-overlapping Intervals MEDIUM

Problem: Return the minimum number of intervals to remove so the rest are non-overlapping.

Minimum Arrows to Burst Balloons MEDIUM

Problem: Balloons span [start,end] on a wall. An arrow at x bursts every balloon covering x. Return the fewest arrows to burst all.

Merge Intervals MEDIUM

Problem: Merge all overlapping intervals and return the resulting non-overlapping intervals.

Hand of Straights MEDIUM

Problem: Can the hand be rearranged into groups of group_size consecutive cards? Return True or False.

Minimum Increments to Make Array Unique MEDIUM

Problem: You may increment elements by 1 repeatedly. Return the minimum number of increments to make every value unique.

Candy HARD

Problem: Each child has a rating. Every child gets >=1 candy and a child with a higher rating than a neighbor gets more candy. Return the minimum total candies.
def candy_greedy(ratings):
    n = len(ratings)
    give = [1] * n
    for i in range(1, n):
        if ratings[i] > ratings[i - 1]:
            give[i] = give[i - 1] + 1
    for i in range(n - 2, -1, -1):
        if ratings[i] > ratings[i + 1]:
            give[i] = max(give[i], give[i + 1] + 1)
    return sum(give)

Remove K Digits HARD

Problem: Remove k digits from the number string so the remaining number is as small as possible. Return it without leading zeros.
def remove_k_digits(num, k):
    stack = []
    for d in num:
        while k and stack and stack[-1] > d:
            stack.pop(); k -= 1
        stack.append(d)
    stack = stack[:len(stack) - k] if k else stack
    return ''.join(stack).lstrip('0') or '0'

Reorganize String HARD

Problem: Rearrange the string so no two adjacent characters are the same. Return any valid arrangement, or '' if impossible.
def reorganize_string(s):
    import heapq
    from collections import Counter
    heap = [(-c, ch) for ch, c in Counter(s).items()]
    heapq.heapify(heap)
    prev = None
    out = []
    while heap:
        cnt, ch = heapq.heappop(heap)
        out.append(ch)
        if prev and prev[0] < 0:
            heapq.heappush(heap, prev)
        prev = (cnt + 1, ch)
    result = ''.join(out)
    return result if len(result) == len(s) else ''

IPO (Maximize Capital) HARD

Problem: Start with capital w. Each project needs capital[i] to start and yields profit[i]. Complete at most k projects to maximize final capital.

Minimum Taps to Water a Garden HARD

Problem: Garden is [0,n]. Tap i covers [i-ranges[i], i+ranges[i]]. Return the fewest taps to water the whole garden, or -1.

Video Stitching HARD

Problem: Given clips [start,end], return the fewest clips needed to cover [0, time], or -1 if impossible.

Two City Scheduling HARD

Problem: costs[i] = [cost_to_A, cost_to_B]. Send exactly half the people to each city, minimizing total cost.

Connect Sticks at Minimum Cost HARD

Problem: Combining two sticks costs the sum of their lengths and produces one stick. Return the minimum cost to combine all sticks into one.

Car Fleet HARD

Problem: Cars at positions with speeds head to a target. Slower cars ahead cap faster ones behind into fleets. Return the number of fleets that arrive.

Bag of Tokens HARD

Problem: Each token can be played face-up (spend token value, gain 1 point, needs enough power) or face-down (spend 1 point, gain its power). Maximize points.

Data Structures & Design

Min Stack EASY

Problem: Design a stack that supports push, pop, top, and retrieving the minimum element, all in O(1). Operations are given as a list; return each op's result (None for void ops).
class MinStack:
    def __init__(self):
        self.stack = []
        self.mins = []
    def push(self, x):
        self.stack.append(x)
        self.mins.append(x if not self.mins else min(x, self.mins[-1]))
    def pop(self):
        self.mins.pop()
        return self.stack.pop()
    def top(self):
        return self.stack[-1]
    def getMin(self):
        return self.mins[-1]

def min_stack_ops(ops):
    obj = MinStack()
    out = []
    for op in ops:
        r = getattr(obj, op[0])(*op[1:])
        out.append(r if op[0] in ('top', 'getMin') else None)
    return out

Queue Using Two Stacks EASY

Problem: Implement a FIFO queue using only two stacks. Support push, pop, peek, empty. Return each op's result.
class MyQueue:
    def __init__(self):
        self.a = []
        self.b = []
    def push(self, x):
        self.a.append(x)
    def _shift(self):
        if not self.b:
            while self.a:
                self.b.append(self.a.pop())
    def pop(self):
        self._shift()
        return self.b.pop()
    def peek(self):
        self._shift()
        return self.b[-1]
    def empty(self):
        return not self.a and not self.b

def queue_using_stacks(ops):
    obj = MyQueue()
    out = []
    for op in ops:
        r = getattr(obj, op[0])(*op[1:])
        out.append(r if op[0] in ('pop', 'peek', 'empty') else None)
    return out

Stack Using Two Queues EASY

Problem: Implement a LIFO stack using two queues. Support push, pop, top, empty. Return each op's result.
from collections import deque
class MyStack:
    def __init__(self):
        self.q = deque()
    def push(self, x):
        self.q.append(x)
        for _ in range(len(self.q) - 1):
            self.q.append(self.q.popleft())
    def pop(self):
        return self.q.popleft()
    def top(self):
        return self.q[0]
    def empty(self):
        return not self.q

def stack_using_queues(ops):
    obj = MyStack()
    out = []
    for op in ops:
        r = getattr(obj, op[0])(*op[1:])
        out.append(r if op[0] in ('pop', 'top', 'empty') else None)
    return out

Moving Average From Data Stream EASY

Problem: Given a window size, return the moving average of the last size values after each new value arrives.

Design HashSet EASY

Problem: Design a hash set supporting add, remove, and contains without using a built-in set. Return the result of each contains call (None for void ops).

Design HashMap EASY

Problem: Design a hash map supporting put, get (return -1 if absent), and remove without built-in dict. Return each get result.

Logger Rate Limiter EASY

Problem: Each message may be printed only if it hasn't been printed in the last 10 seconds. Given [timestamp, message] pairs, return True/False for each (whether it prints).

Range Sum Query (Immutable) EASY

Problem: Precompute prefix sums so each query [i, j] returns the sum of nums[i..j] in O(1). Return the answers.

Design Parking System EASY

Problem: A parking lot has a fixed number of big, medium, and small spots. For each incoming car (type 1/2/3), return whether it can park.

Number of Recent Calls EASY

Problem: Each ping arrives at a timestamp. After each ping, return how many pings occurred in the last 3000 ms (inclusive).

BST Construction MEDIUM

class BST:
    def __init__(self, value):
        self.value = value; self.left = None; self.right = None
    def insert(self, value):
        node = self
        while True:
            if value < node.value:
                if node.left is None: node.left = BST(value); break
                node = node.left
            else:
                if node.right is None: node.right = BST(value); break
                node = node.right
        return self
    def contains(self, value):
        node = self
        while node:
            if value < node.value: node = node.left
            elif value > node.value: node = node.right
            else: return True
        return False

Min Heap (with Python's heapq) MEDIUM

import heapq
nums = [5, 2, 8, 1]
heapq.heapify(nums)         # O(n) -> smallest is always nums[0]
heapq.heappush(nums, 3)     # O(log n)
smallest = heapq.heappop(nums)   # remove + return the min, O(log n)
# Max-heap trick: push/pop the NEGATIVE of each value

Suffix Trie Construction MEDIUM

class SuffixTrie:
    def __init__(self, string):
        self.root = {}; self.end = "*"
        for i in range(len(string)):
            self._insert(string[i:])
    def _insert(self, s):
        node = self.root
        for ch in s: node = node.setdefault(ch, {})
        node[self.end] = True
    def contains(self, s):
        node = self.root
        for ch in s:
            if ch not in node: return False
            node = node[ch]
        return self.end in node

LRU Cache MEDIUM

Problem: Design a Least-Recently-Used cache with a capacity, supporting get (return -1 if absent) and put in O(1). Return each get result.

Design Circular Queue MEDIUM

Problem: Implement a fixed-size circular queue supporting enQueue, deQueue, Front, Rear, isEmpty, isFull. Return each op's result.

Time-Based Key-Value Store MEDIUM

Problem: Store multiple values per key with timestamps. get(key, t) returns the value set at the greatest timestamp <= t (or '' if none). Return each get result.

Design Underground System MEDIUM

Problem: Track passenger check-ins and check-outs at stations. getAverageTime(start, end) returns the average travel time between two stations. Return query results (None for void ops).

Design Browser History MEDIUM

Problem: Start on a homepage. visit(url) clears forward history. back(steps) and forward(steps) move within history and return the current url. Return each back/forward result.

Online Stock Span MEDIUM

Problem: For each daily price, return the stock span: the number of consecutive days up to today with a price <= today's price.

Design Front Middle Back Queue MEDIUM

Problem: Support pushFront, pushMiddle, pushBack, popFront, popMiddle, popBack. Pops return -1 if empty. Return each pop's result (None for void ops).

My Calendar I MEDIUM

Problem: Book events [start, end). A booking succeeds only if it does not overlap an existing one. Return True/False for each booking.

Range Sum Query (Mutable) MEDIUM

Problem: Support update(i, val) and sumRange(i, j) with a Binary Indexed (Fenwick) Tree. Return each sumRange result (None for updates).

Design Circular Deque MEDIUM

Problem: Implement a fixed-size circular double-ended queue: insertFront, insertLast, deleteFront, deleteLast, getFront, getRear, isEmpty, isFull. Return each op's result.

LRU Cache HARD

Get/put in O(1), evicting the least-recently-used item. An OrderedDict does the heavy lifting.

from collections import OrderedDict
class LRUCache:
    def __init__(self, capacity):
        self.cache = OrderedDict(); self.capacity = capacity
    def get(self, key):
        if key not in self.cache: return -1
        self.cache.move_to_end(key)         # mark most-recently-used
        return self.cache[key]
    def put(self, key, value):
        if key in self.cache: self.cache.move_to_end(key)
        self.cache[key] = value
        if len(self.cache) > self.capacity:
            self.cache.popitem(last=False)  # evict least-recently-used

Knuth-Morris-Pratt (string search) HARD

Find a pattern in text in O(n+m) using a precomputed "failure" table.

class Solution:
    def kmp_search(self, text, pattern):
        lps = [0] * len(pattern)          # longest prefix = suffix table
        k = 0
        for i in range(1, len(pattern)):
            while k > 0 and pattern[i] != pattern[k]: k = lps[k-1]
            if pattern[i] == pattern[k]: k += 1
            lps[i] = k
        j = 0
        for i in range(len(text)):
            while j > 0 and text[i] != pattern[j]: j = lps[j-1]
            if text[i] == pattern[j]: j += 1
            if j == len(pattern): return i - j + 1   # start index of match
        return -1

LFU Cache HARD

Problem: Design a Least-Frequently-Used cache; ties are broken by least-recently-used. Support get (-1 if absent) and put in O(1). Return each get result.
from collections import defaultdict, OrderedDict
class LFUCache:
    def __init__(self, capacity):
        self.cap = capacity
        self.vals = {}
        self.freq = {}
        self.groups = defaultdict(OrderedDict)
        self.min_freq = 0
    def _bump(self, key):
        f = self.freq[key]
        del self.groups[f][key]
        if not self.groups[f]:
            del self.groups[f]
            if self.min_freq == f:
                self.min_freq += 1
        self.freq[key] = f + 1
        self.groups[f + 1][key] = None
    def get(self, key):
        if key not in self.vals:
            return -1
        self._bump(key)
        return self.vals[key]
    def put(self, key, value):
        if self.cap == 0:
            return
        if key in self.vals:
            self.vals[key] = value
            self._bump(key)
            return
        if len(self.vals) >= self.cap:
            evict, _ = self.groups[self.min_freq].popitem(last=False)
            del self.vals[evict]
            del self.freq[evict]
        self.vals[key] = value
        self.freq[key] = 1
        self.groups[1][key] = None
        self.min_freq = 1

def lfu_cache_ops(capacity, ops):
    obj = LFUCache(capacity)
    out = []
    for op in ops:
        r = getattr(obj, op[0])(*op[1:])
        out.append(r if op[0] == 'get' else None)
    return out

Find Median From Data Stream HARD

Problem: Support addNum(x) and findMedian(). Maintain a max-heap (low half) and min-heap (high half). Return each findMedian result (None for adds).

Add and Search Word (Wildcards) HARD

Problem: Design a dictionary with addWord and search, where search supports '.' matching any single letter. Return each search result (None for adds).

My Calendar II (No Triple Booking) HARD

Problem: Book events [start, end). A booking is allowed unless it would cause a triple booking. Return True/False for each booking.

My Calendar III (Max K-Booking) HARD

Problem: After each booking [start, end), return the maximum number of events overlapping at any single point in time, using a sweep-line count.

Snapshot Array HARD

Problem: Design an array of a given length that supports set(index, val), snap() (returns a snapshot id), and get(index, snap_id). Use per-index history + binary search. Return snap ids and get results (None for sets).

Stock Price Fluctuation HARD

Problem: Records arrive as (timestamp, price) and timestamps may be corrected later. Support update, current (latest price), maximum, minimum. Return each query result (None for updates).

Range Module HARD

Problem: Track ranges of numbers. Support addRange(l, r), queryRange(l, r) (are all numbers in [l,r) tracked?), and removeRange(l, r). Return each queryRange result (None for void ops).

Maximum Frequency Stack HARD

Problem: Design a stack where pop() removes and returns the most frequent element; ties are broken by the most recently pushed. Return each pop result (None for pushes).

Authentication Manager HARD

Problem: Tokens expire ttl seconds after their last use. Support generate(id, t), renew(id, t) (only if unexpired), and countUnexpiredTokens(t). Return each count result (None for void ops).

Java

Binary Search (Java) EASY

Iterative binary search with the overflow-safe midpoint. O(log n) time, O(1) space.

public static int binarySearch(int[] arr, int target) {
    int lo = 0, hi = arr.length - 1;
    while (lo <= hi) {
        int mid = lo + (hi - lo) / 2;      // avoids (lo+hi) overflow
        if (arr[mid] == target) return mid;
        if (arr[mid] < target) lo = mid + 1;
        else                   hi = mid - 1;
    }
    return -1;                             // not found
}

Reverse an Array In Place (Java) EASY

Problem: Reverse an int array in place using two pointers.
    static void reverse(int[] a) {
        int lo = 0, hi = a.length - 1;
        while (lo < hi) {
            int tmp = a[lo]; a[lo] = a[hi]; a[hi] = tmp;
            lo++; hi--;
        }
    }

FizzBuzz (Java) EASY

Problem: Return the FizzBuzz sequence from 1 to n: multiples of 3 are 'Fizz', of 5 'Buzz', of both 'FizzBuzz'.
    static List<String> fizzBuzz(int n) {
        List<String> res = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            if (i % 15 == 0) res.add("FizzBuzz");
            else if (i % 3 == 0) res.add("Fizz");
            else if (i % 5 == 0) res.add("Buzz");
            else res.add(String.valueOf(i));
        }
        return res;
    }

Find Maximum in an Array (Java) EASY

Problem: Return the largest value in a non-empty int array.

Sum of an Array (Java) EASY

Problem: Return the sum of all elements in an int array.

Palindrome Check (Java) EASY

Problem: Return true if the string reads the same forwards and backwards.

Count Vowels (Java) EASY

Problem: Return the number of vowels (a, e, i, o, u) in the string.

Factorial (Java) EASY

Problem: Compute n! iteratively using a long to hold the result.

Greatest Common Divisor (Java) EASY

Problem: Compute gcd(a, b) with the iterative Euclidean algorithm.

Linear Search (Java) EASY

Problem: Return the index of target in the array, or -1 if it is absent.

Bubble Sort (Java) EASY

Problem: Sort an int array ascending using bubble sort with an early-exit optimization.

Breadth-First Search (Java) MEDIUM

Queue-based BFS over an adjacency map. Mark nodes seen at enqueue time so cycles can't loop. O(V+E).

import java.util.*;

public static List<Integer> bfs(Map<Integer, List<Integer>> graph, int start) {
    List<Integer> order = new ArrayList<>();
    Set<Integer> seen  = new HashSet<>();
    Queue<Integer> queue = new LinkedList<>();
    queue.add(start); seen.add(start);

    while (!queue.isEmpty()) {
        int node = queue.poll();
        order.add(node);
        for (int next : graph.getOrDefault(node, List.of())) {
            if (!seen.contains(next)) {    // seen-before-enqueue stops cycles
                seen.add(next);
                queue.add(next);
            }
        }
    }
    return order;
}

Longest Common Subsequence (Java) MEDIUM

Bottom-up DP — the plagiarism-detector algorithm in Java. O(n·m) time and space.

public static int lcs(String a, String b) {
    int n = a.length(), m = b.length();
    int[][] dp = new int[n + 1][m + 1];
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a.charAt(i - 1) == b.charAt(j - 1))
                dp[i][j] = 1 + dp[i - 1][j - 1];
            else
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
        }
    }
    return dp[n][m];
}

Two Sum (Java) MEDIUM

Problem: Return the indices of the two numbers that add up to target, using a HashMap in one pass.
    static int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> seen = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int need = target - nums[i];
            if (seen.containsKey(need)) return new int[]{seen.get(need), i};
            seen.put(nums[i], i);
        }
        return new int[]{-1, -1};
    }

Merge Two Sorted Arrays (Java) MEDIUM

Problem: Merge two sorted int arrays into a single sorted array.

Valid Parentheses (Java) MEDIUM

Problem: Return true if the bracket string is balanced, using a Deque as a stack.

First Unique Character (Java) MEDIUM

Problem: Return the index of the first non-repeating character in the string, or -1 if none.

Move Zeroes (Java) MEDIUM

Problem: Move all zeroes to the end of the array in place while keeping the order of the non-zero elements.

Rotate Array (Java) MEDIUM

Problem: Rotate the array to the right by k steps in place using the reversal trick.

Maximum Subarray - Kadane (Java) MEDIUM

Problem: Return the largest sum of any contiguous subarray using Kadane's algorithm.

Group Anagrams (Java) MEDIUM

Problem: Group the words that are anagrams of one another, keying a HashMap by the sorted characters.

Quicksort (Java) MEDIUM

Problem: Sort an int array ascending using in-place quicksort with the Lomuto partition scheme.

Merge Sort (Java) MEDIUM

Problem: Sort an int array ascending using recursive merge sort.

Edit Distance (Java) HARD

Levenshtein distance, bottom-up. O(n·m).

public static int editDistance(String a, String b) {
    int n = a.length(), m = b.length();
    int[][] dp = new int[n + 1][m + 1];
    for (int i = 0; i <= n; i++) dp[i][0] = i;   // delete all of a[:i]
    for (int j = 0; j <= m; j++) dp[0][j] = j;   // insert all of b[:j]

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a.charAt(i - 1) == b.charAt(j - 1))
                dp[i][j] = dp[i - 1][j - 1];
            else
                dp[i][j] = 1 + Math.min(dp[i - 1][j - 1],
                              Math.min(dp[i - 1][j], dp[i][j - 1]));
        }
    }
    return dp[n][m];
}

OOP Design — Cloud E-Reader (Java) HARD

The same design as the Python version, in idiomatic Java with a HashMap collection.

import java.util.*;

class Book {
    int id; String title; List<String> content; int lastPage = 0;
    Book(int id, String title, List<String> content) {
        this.id = id; this.title = title; this.content = content;
    }
    String displayPage() { return content.get(lastPage); }
    String turnPage() {
        if (lastPage < content.size() - 1) lastPage++;
        return displayPage();
    }
}

class Library {
    private Map<Integer, Book> collection = new HashMap<>();
    private Integer activeId = null;
    private int nextId = 0;

    int addBook(String title, List<String> content) {
        Book b = new Book(nextId++, title, content);
        collection.put(b.id, b);
        return b.id;
    }
    void removeBook(int id) {
        collection.remove(id);
        if (activeId != null && activeId == id) activeId = null;
    }
    void setActive(int id) { if (collection.containsKey(id)) activeId = id; }
    String displayPage() { return activeId == null ? null : collection.get(activeId).displayPage(); }
    String turnPage()    { return activeId == null ? null : collection.get(activeId).turnPage(); }
}

Dijkstra's Shortest Path (Java) HARD

Problem: Given a weighted adjacency matrix (0 = no edge), return the shortest distance from a source to every node using a PriorityQueue.
    static int[] dijkstra(int[][] graph, int src) {
        int n = graph.length;
        int[] dist = new int[n];
        Arrays.fill(dist, Integer.MAX_VALUE);
        dist[src] = 0;
        boolean[] done = new boolean[n];
        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] - b[1]);
        pq.add(new int[]{src, 0});
        while (!pq.isEmpty()) {
            int u = pq.poll()[0];
            if (done[u]) continue;
            done[u] = true;
            for (int v = 0; v < n; v++) {
                if (graph[u][v] > 0 && dist[u] + graph[u][v] < dist[v]) {
                    dist[v] = dist[u] + graph[u][v];
                    pq.add(new int[]{v, dist[v]});
                }
            }
        }
        return dist;
    }

LRU Cache (Java) HARD

Problem: Design a Least-Recently-Used cache with a fixed capacity using LinkedHashMap in access order.

Trie (Prefix Tree) (Java) HARD

Problem: Implement a trie supporting insert, search (full word), and startsWith (prefix).

Topological Sort - Kahn's (Java) HARD

Problem: Return a topological ordering of n nodes given directed edges, using Kahn's in-degree algorithm.

0/1 Knapsack (Java) HARD

Problem: Given item weights and values and a capacity, return the maximum value achievable using a 1-D DP.

Longest Increasing Subsequence (Java) HARD

Problem: Return the length of the longest strictly increasing subsequence in O(n log n) using patience sorting.

Median of Two Sorted Arrays (Java) HARD

Problem: Return the median of two sorted arrays in O(log(min(m,n))) using a binary-search partition.

N-Queens (Count) (Java) HARD

Problem: Count the number of distinct solutions to the n-queens puzzle using bitmask backtracking.

Coin Change (Java) HARD

Problem: Given coin denominations and a target amount, return the fewest coins needed to make the amount, or -1 if impossible.

Union-Find / Disjoint Set (Java) HARD

Problem: Implement union-find with path compression and union by rank; count the connected components after a series of unions.

Real-world & On-the-job

API + JSON — revenue by product EASY

Integration roles live on this: call a REST endpoint that returns a JSON list of orders and aggregate revenue per product, highest first. Standard library only — no external packages.

import json, urllib.request
from collections import defaultdict

def revenue_by_product(url):
    with urllib.request.urlopen(url, timeout=10) as resp:
        orders = json.load(resp)        # [{"product": "...", "price": 9.99, "qty": 2}, ...]

    totals = defaultdict(float)
    for o in orders:
        totals[o["product"]] += o["price"] * o["qty"]

    # highest-grossing first
    return sorted(totals.items(), key=lambda kv: kv[1], reverse=True)

SQL — group, filter & rank customers EASY

From Orders(id, customer_id, amount), list customers with more than 3 orders plus their total spend, biggest spenders first. Tests GROUP BY / HAVING / ORDER BY.

SELECT customer_id,
       COUNT(*)    AS order_count,
       SUM(amount) AS total_spent
FROM   Orders
GROUP BY customer_id
HAVING COUNT(*) > 3
ORDER BY total_spent DESC;

Unit testing / TDD EASY

Every listing wants tests, code reviews and Agile. Given is_valid_email, write tests that cover the happy path and the edge cases (missing @, empty, double @). Interviewers love when you test before you trust the code.

import unittest

def is_valid_email(s):
    return s.count("@") == 1 and "." in s.split("@")[1]

class TestEmail(unittest.TestCase):
    def test_valid(self):    self.assertTrue(is_valid_email("[email protected]"))
    def test_no_at(self):    self.assertFalse(is_valid_email("abc.com"))
    def test_empty(self):    self.assertFalse(is_valid_email(""))
    def test_two_ats(self):  self.assertFalse(is_valid_email("a@@b.com"))

if __name__ == "__main__":
    unittest.main()

Parse a Query String EASY

Problem: Parse a URL query string like 'a=1&b=2&c=3' into a dictionary of key/value pairs.

Convert camelCase to snake_case EASY

Problem: Convert a camelCase identifier into snake_case (e.g. 'firstName' -> 'first_name').

Convert snake_case to camelCase EASY

Problem: Convert a snake_case identifier into camelCase (e.g. 'first_name' -> 'firstName').

Format Cents as Currency EASY

Problem: Given an integer number of cents, return a formatted dollar string with thousands separators, e.g. 123456 -> '$1,234.56'.

Truncate Text With Ellipsis EASY

Problem: If the text is longer than max_len, cut it to max_len characters and append '...'; otherwise return it unchanged.

Slugify a Title EASY

Problem: Turn a title into a URL slug: lowercase, spaces to hyphens, and drop characters that aren't letters, digits, or hyphens.

Count Words in Text EASY

Problem: Return the number of whitespace-separated words in a block of text.

Validate an Email Address EASY

Problem: Return True if the string looks like a basic email: exactly one '@', non-empty local and domain parts, and a dot in the domain.

Mask a Credit Card Number EASY

Problem: Return the card number with every digit hidden as '*' except the last four.

Celsius to Fahrenheit EASY

Problem: Convert a Celsius temperature to Fahrenheit, rounded to one decimal place.

Plagiarism Detector — Longest Common Subsequence MEDIUM

To flag plagiarism between two stories, find the length of their longest shared subsequence of characters (same order, but gaps allowed). The naive "try every substring" approach is exponential; memoized recursion is O(n·m). Then run it over every pair of books to surface the most-likely match.

from functools import lru_cache

def longest_common_subsequence(a, b):
    @lru_cache(maxsize=None)
    def lcs(i, j):
        if i == len(a) or j == len(b):
            return 0
        if a[i] == b[j]:
            return 1 + lcs(i + 1, j + 1)            # match -> advance both
        return max(lcs(i + 1, j), lcs(i, j + 1))    # else skip one side
    return lcs(0, 0)

def most_likely_plagiarism(books):                  # books: list[(title, text)]
    best = (0, None, None)
    for i in range(len(books)):
        for j in range(i + 1, len(books)):
            score = longest_common_subsequence(books[i][1], books[j][1])
            if score > best[0]:
                best = (score, books[i][0], books[j][0])
    return best                                     # (shared_chars, titleA, titleB)

SQL — second-highest salary MEDIUM

SQL was the single most-requested hard skill across the listings. From Employee(id, name, salary), return the second-highest distinct salary (return NULL if there isn't one). Know both the sub-query and the window-function answer.

-- Classic sub-query
SELECT MAX(salary) AS second_highest
FROM   Employee
WHERE  salary < (SELECT MAX(salary) FROM Employee);

-- Modern, scales to "Nth highest" (window function)
SELECT DISTINCT salary AS second_highest
FROM (
    SELECT salary,
           DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
    FROM   Employee
) ranked
WHERE rnk = 2;

SQL — top earner per department MEDIUM

Join + correlated sub-query, a daily-driver pattern for data roles. List each department and the employee(s) earning the most within that department.

SELECT d.name AS department,
       e.name AS employee,
       e.salary
FROM   Employee  e
JOIN   Department d ON e.dept_id = d.id
WHERE  e.salary = (
    SELECT MAX(e2.salary)
    FROM   Employee e2
    WHERE  e2.dept_id = e.dept_id
)
ORDER BY d.name;

Parse a CSV Line With Quotes MEDIUM

Problem: Split a single CSV line into fields, respecting double-quoted fields that may contain commas.

Group Records by a Key MEDIUM

Problem: Given a list of dictionaries, group them into a dict of lists keyed by the value of the given field.

Flatten a Nested Dictionary MEDIUM

Problem: Flatten a nested dictionary into a single level, joining nested keys with dots (e.g. {'a':{'b':1}} -> {'a.b':1}).

Deep Merge Two Dictionaries MEDIUM

Problem: Merge dictionary b into a recursively: nested dicts merge, and b's values win on conflicts. Return the merged result.

Rate Limit Check MEDIUM

Problem: Given past request timestamps, a new timestamp, a limit, and a window, return True if allowing the new request stays within limit requests per window.

Paginate a List MEDIUM

Problem: Return the slice of items for the given 1-based page number and page size.

Parse a Duration String MEDIUM

Problem: Parse a duration like '1h30m15s' into a total number of seconds.

Deduplicate Preserving Order MEDIUM

Problem: Remove duplicate items from a list while keeping the order of first appearance.

Exponential Backoff Delays MEDIUM

Problem: Return the list of retry delays for the given number of attempts using exponential backoff (base * 2^i), capped at max_delay.

Top N Items by Frequency MEDIUM

Problem: Return the n most frequent items as (item, count) pairs, ordered by descending count (ties by first appearance).

OOP System Design — Cloud E-Reader HARD

Design the core classes for an online cloud reading app (think Kindle, but for indie short stories). Requirements: a user has a library of books they can add to / remove from; they can set one book active; the app remembers where they left off in each book; and it shows one page at a time of the active book. Keep the Book and Library responsibilities separate so the storage format can change later.

class Book:
    """One story. content = list of page-strings; remembers the reader's spot."""
    def __init__(self, book_id, title, content):
        self.id = book_id
        self.title = title
        self.content = content          # list[str], one entry per page
        self.last_page = 0              # index into content

    def display_page(self):
        return self.content[self.last_page]

    def turn_page(self):
        if self.last_page < len(self.content) - 1:
            self.last_page += 1
        return self.display_page()


class Library:
    """A reader's collection of books + which one is open right now."""
    def __init__(self):
        self.collection = {}            # id -> Book  (dict = O(1) lookup)
        self.active_id = None
        self._next_id = 0               # simple unique-id generator

    def add_book(self, title, content):
        book = Book(self._next_id, title, content)
        self.collection[book.id] = book
        self._next_id += 1
        return book.id

    def remove_book(self, book_id):
        self.collection.pop(book_id, None)
        if self.active_id == book_id:
            self.active_id = None

    def set_active(self, book_id):
        if book_id in self.collection:
            self.active_id = book_id

    def display_page(self):
        if self.active_id is None: return None
        return self.collection[self.active_id].display_page()

    def turn_page(self):
        if self.active_id is None: return None
        return self.collection[self.active_id].turn_page()

# Follow-ups the interviewer will ask:
#  • Bigger font? Store content as ONE string + a Display class that computes
#    chars_per_page from font_size, then page n = content[n*cpp : (n+1)*cpp].
#  • Many users sharing books? Store each Book ONCE (e.g. a SQL table keyed by a
#    global id); keep per-user state (active_id, last_page) in a separate UserState.

Edit Distance (Levenshtein) HARD

The other DP every fuzzy-matching/plagiarism system uses: minimum single-character insert / delete / replace edits to turn string a into b. Bottom-up table, O(n·m).

def edit_distance(a, b):
    n, m = len(a), len(b)
    dp = [[0] * (m + 1) for _ in range(n + 1)]
    for i in range(n + 1): dp[i][0] = i        # delete all of a[:i]
    for j in range(m + 1): dp[0][j] = j        # insert all of b[:j]

    for i in range(1, n + 1):
        for j in range(1, m + 1):
            if a[i-1] == b[j-1]:
                dp[i][j] = dp[i-1][j-1]         # chars match -> free
            else:
                dp[i][j] = 1 + min(dp[i-1][j],      # delete
                                   dp[i][j-1],      # insert
                                   dp[i-1][j-1])    # replace
    return dp[n][m]

Compare Semantic Versions HARD

Problem: Compare two semantic version strings like '1.2.10' and '1.2.3'. Return -1, 0, or 1 (missing components count as 0).
def compare_versions(a, b):
    pa = [int(x) for x in a.split('.')]
    pb = [int(x) for x in b.split('.')]
    length = max(len(pa), len(pb))
    pa += [0] * (length - len(pa))
    pb += [0] * (length - len(pb))
    for x, y in zip(pa, pb):
        if x < y:
            return -1
        if x > y:
            return 1
    return 0

Parse CSV Into Records HARD

Problem: Given CSV text where the first row is the header, return a list of dictionaries mapping each column name to its value.

Get a Value by Dotted Path HARD

Problem: Given a nested structure of dicts and lists, return the value at a dotted path like 'user.roles.0.name', or None if any step is missing.

Validate a Password HARD

Problem: Return a list of failed rules for a password: at least 8 chars, one uppercase, one lowercase, one digit, one special character. Empty list means valid.

Diff Two Lists HARD

Problem: Compare an old and a new list and return a dict with the 'added' items (in new, not old) and 'removed' items (in old, not new), preserving order.

Parse an INI Config HARD

Problem: Parse simple INI text into a dict of sections, each a dict of key/value pairs. Ignore blank lines and ';' comments.

Expand a Range Expression HARD

Problem: Expand a compact range string like '1-3,5,7-9' into the sorted list of integers it represents.

Format an Aligned Text Table HARD

Problem: Given rows of strings, return a single string where columns are left-aligned and padded to the width of the widest cell, rows joined by newlines.

Normalize a File Path HARD

Problem: Simplify a Unix-style path, resolving '.' and '..' segments and collapsing repeated slashes. Return the canonical absolute path.

Parse a Web Server Log Line HARD

Problem: Parse a Common Log Format line into a dict with ip, method, path, status, and size fields.

🏢 Real-world & on-the-job problems

Pulled straight from what 2026 job listings actually ask for — across data, finance, cloud and full-stack roles the recurring hard skills are SQL, OOP/system design, dynamic programming, APIs/JSON and unit testing. These are worked end-to-end, the way a real 45-minute interview runs (design first, then an algorithm). The two headline problems below are the exact format of a full-length mock interview: an open-ended OOP design, then a DP algorithm.

Mixed & Hardest

Optimal Freelancing EASY

Max profit picking jobs (1 day each) by their deadlines within a 7-day week. Greedy by pay.

class Solution:
    def optimal_freelancing(self, jobs):
        LIMIT = 7
        jobs.sort(key=lambda j: j["payment"], reverse=True)
        taken = [False] * LIMIT; profit = 0
        for job in jobs:
            for day in range(min(job["deadline"], LIMIT) - 1, -1, -1):
                if not taken[day]:
                    taken[day] = True; profit += job["payment"]; break
        return profit

Knight Connection (two knights meet) MEDIUM

Min total moves for two knights to land on the same square. BFS from one; they move alternately.

from collections import deque

class Solution:
    def knight_connection(self, a, b):
        moves = [(2,1),(2,-1),(-2,1),(-2,-1),(1,2),(1,-2),(-1,2),(-1,-2)]
        q = deque([(a[0], a[1], 0)]); seen = {tuple(a)}
        while q:
            r, c, d = q.popleft()
            if [r, c] == b: return (d + 1) // 2
            for dr, dc in moves:
                nxt = (r + dr, c + dc)
                if nxt not in seen:
                    seen.add(nxt); q.append((nxt[0], nxt[1], d + 1))

Split Binary Tree MEDIUM

Can one cut split the tree into two equal-sum halves? Returns that half-sum or 0.

class Solution:
    def split_binary_tree(self, tree):
        def total(node):
            return 0 if not node else node.value + total(node.left) + total(node.right)
        whole = total(tree)
        if whole % 2: return 0
        found = [False]
        def helper(node):
            if not node: return 0
            s = node.value + helper(node.left) + helper(node.right)
            if s == whole // 2: found[0] = True
            return s
        helper(tree)
        return whole // 2 if found[0] else 0

Merging Linked Lists (find intersection) MEDIUM

Where two lists join. Swap each pointer to the other list's head when it ends — they meet at the join. O(n).

class Solution:
    def merging_linked_lists(self, l1, l2):
        a, b = l1, l2
        while a != b:
            a = a.next if a else l2
            b = b.next if b else l1
        return a            # the shared node (or None)

Min Heap Construction (from scratch) MEDIUM

Juice Bottling MEDIUM

Split N liters into bottle sizes to maximize total price (like rod-cutting), returning the split. O(n²).

Zero Sum Subarray MEDIUM

Does any subarray sum to 0? If a running sum repeats, the slice between is 0. O(n).

Binary Tree Diameter MEDIUM

Minimum Passes Of Matrix MEDIUM

Each pass, positives convert their negative neighbors. How many passes to flip all? Multi-source BFS. O(w·h).

Best Digits (remove k to maximize) MEDIUM

Colliding Asteroids MEDIUM

Positive = moving right, negative = left. Use a stack; resolve collisions. O(n).

Minimum Characters For Words MEDIUM

Longest Balanced Substring HARD

Longest run of valid () parentheses. Stack of indices. O(n).

class Solution:
    def longest_balanced(self, s):
        stack = [-1]; longest = 0
        for i, ch in enumerate(s):
            if ch == "(":
                stack.append(i)
            else:
                stack.pop()
                if not stack: stack.append(i)
                else: longest = max(longest, i - stack[-1])
        return longest

Right Smaller Than HARD

For each element, how many to its right are smaller. Insert into a sorted list from the right. O(n²) (O(n log n) with a BIT).

import bisect

class Solution:
    def right_smaller_than(self, arr):
        res = [0] * len(arr); sorted_seen = []
        for i in range(len(arr) - 1, -1, -1):
            pos = bisect.bisect_left(sorted_seen, arr[i])
            res[i] = pos
            sorted_seen.insert(pos, arr[i])
        return res

Maximize Expression HARD

Maximize a[i]−a[j]+a[k]−a[l] for i<j<k<l. Build four running-best arrays. O(n).

class Solution:
    def maximize_expression(self, arr):
        n = len(arr)
        if n < 4: return 0
        maxA = [arr[0]] * n
        for i in range(1, n): maxA[i] = max(maxA[i-1], arr[i])
        maxAB = [float("-inf")] * n
        for i in range(1, n): maxAB[i] = max(maxAB[i-1], maxA[i-1] - arr[i])
        maxABC = [float("-inf")] * n
        for i in range(2, n): maxABC[i] = max(maxABC[i-1], maxAB[i-1] + arr[i])
        maxABCD = [float("-inf")] * n
        for i in range(3, n): maxABCD[i] = max(maxABCD[i-1], maxABC[i-1] - arr[i])
        return maxABCD[n-1]

Repair BST (two nodes swapped) HARD

An in-order walk of a BST is sorted — the two out-of-order nodes are the swapped pair. O(n).

Validate Three Nodes HARD

Is the middle node a descendant of one outer node and an ancestor of the other? O(h).

Line Through Points HARD

Max points on a single straight line. Group by reduced slope (use gcd to normalize). O(n²).

Stable Internships (Gale-Shapley) HARD

Match interns ↔ teams so no pair would both rather swap. The classic stable-matching algorithm.

Shortest Unique Prefixes HARD

Shortest prefix of each word that no other word shares. Trie with counts. O(total chars).

Square of Zeroes HARD

Is there a square whose border is all 0s? Precompute consecutive zeros right/down, then check each square. O(n³).

Optimal Assembly Line HARD

Min possible max-station-time when splitting ordered steps across k stations. Binary-search the answer. O(n log(sum)).

Pattern Matcher HARD

Given a pattern of x's & y's, find strings for x and y that rebuild s. Try every length of x. O(n²).

Right Sibling Tree HARD

Rewire every node's right to point to its sibling on the same level. Recurse left before mutating right.

Airport Connections HARD

Fewest new routes so every airport is reachable from the start. Score unreachable airports by how many other unreachable ones they unlock; add greedily.

Largest Park HARD

Biggest rectangle of empty land (0s) in a grid. Row-by-row histogram + largest-rectangle. O(rows·cols).

Sum BSTs (count valid BST subtrees) HARD

Doubly Linked List (construction) HARD

Blackjack Probability HARD

Chance the dealer busts (goes over the target). Dealer draws (cards 1–10) until within 4 of target. Memoized.

Two-Edge-Connected Graph HARD

Is the graph connected with no "bridge" edges (every edge lies on a cycle)? DFS arrival/low times (Tarjan). O(V+E).

Count Squares HARD

How many squares can be formed from a set of points? Check each pair as a diagonal. O(n²).

Largest Island HARD

Flip one water cell to land — what's the biggest land block possible? Label regions, then test each water cell. O(w·h).

Sort K-Sorted Array HARD

Every element is at most k spots from its sorted position. A size-(k+1) min-heap. O(n log k).

Merge K Sorted Arrays HARD

Shift Linked List HARD

Rotate a list by k. Make it circular, then break it at the right spot. O(n).

Lowest Common Manager HARD

LCA on an org chart (n-ary tree, no parent links). Count how many of the two appear in each subtree. O(n).

Ambiguous Measurements HARD

Can imprecise measuring cups produce a target range? Memoized recursion.

Shorten Path HARD

Simplify a Unix-style path (handle ., .., extra slashes). Stack. O(n).

Rearrange Linked List (around a value) HARD

Reorder so everything < k comes before == k before > k. Build three sublists, then stitch. O(n).

Laptop Rentals HARD

Min laptops for overlapping rental times. Sort starts & ends, sweep with two pointers. O(n log n).

Strings Made Up Of Strings HARD

Which big strings can be built by concatenating the smaller ones (word-break)? DP per string. O(n·L²).

Longest Most Frequent Prefix HARD

Longest prefix shared by the most strings. Build a counting trie, then follow the most-visited path. O(total chars).

Waterfall Streams HARD

Water poured at a source flows down, splitting 50/50 around walls (1s). Return how much reaches each bottom slot. Row-by-row simulation; carry % as negatives.

🎯 Interview tip: out loud, (1) restate the problem, (2) give a brute-force idea + its Big-O, (3) improve it with a pattern, (4) code it, (5) test on an example and edge cases (empty input, one element). Talking through it matters as much as the answer.

Top 150

🏆 Top 150 Interview Questions

The 150 questions companies ask most, grouped by topic. Below are concise, original Python solutions for each. (Some overlap the classics above; included here so this set is self-contained.)

Array / String

Merge Sorted Array EASY

Merge nums2 into nums1 in place — fill from the back to avoid overwriting. O(m+n).

class Solution:
    def merge(self, nums1, m, nums2, n):
        i, j, k = m - 1, n - 1, m + n - 1
        while j >= 0:
            if i >= 0 and nums1[i] > nums2[j]:
                nums1[k] = nums1[i]; i -= 1
            else:
                nums1[k] = nums2[j]; j -= 1
            k -= 1

Remove Element EASY

class Solution:
    def remove_element(self, nums, val):
        k = 0
        for n in nums:
            if n != val: nums[k] = n; k += 1
        return k

Remove Duplicates from Sorted Array EASY

class Solution:
    def remove_duplicates(self, nums):
        if not nums: return 0
        k = 1
        for i in range(1, len(nums)):
            if nums[i] != nums[k-1]:
                nums[k] = nums[i]; k += 1
        return k

Remove Duplicates from Sorted Array II (keep 2) MEDIUM

class Solution:
    def remove_duplicates_ii(self, nums):
        k = 0
        for n in nums:
            if k < 2 or n != nums[k-2]:
                nums[k] = n; k += 1
        return k

Majority Element EASY

Rotate Array MEDIUM

class Solution:
    def rotate(self, nums, k):
        k %= len(nums)
        nums[:] = nums[-k:] + nums[:-k]

Best Time to Buy and Sell Stock EASY

Best Time to Buy and Sell Stock II MEDIUM

Unlimited trades → grab every upward step. O(n).

class Solution:
    def max_profit_ii(self, prices):
        return sum(max(0, prices[i] - prices[i-1]) for i in range(1, len(prices)))

Jump Game MEDIUM

Jump Game II (min jumps) MEDIUM

H-Index MEDIUM

Insert Delete GetRandom O(1) MEDIUM

Array for O(1) random + dict of value→index; on remove, swap with the last element.

Product of Array Except Self MEDIUM

Prefix products left-to-right, then multiply by suffix products right-to-left. No division. O(n).

Gas Station MEDIUM

Candy HARD

Two passes: reward left-to-right for rising ratings, then right-to-left. O(n).

class Solution:
    def candy(self, ratings):
        n = len(ratings); c = [1] * n
        for i in range(1, n):
            if ratings[i] > ratings[i-1]: c[i] = c[i-1] + 1
        for i in range(n - 2, -1, -1):
            if ratings[i] > ratings[i+1]: c[i] = max(c[i], c[i+1] + 1)
        return sum(c)

Trapping Rain Water HARD

class Solution:
    def trap(self, height):
        left, right = 0, len(height) - 1
        left_max = right_max = water = 0
        while left < right:
            if height[left] < height[right]:
                left_max = max(left_max, height[left])
                water += left_max - height[left]; left += 1
            else:
                right_max = max(right_max, height[right])
                water += right_max - height[right]; right -= 1
        return water

Roman to Integer EASY

Integer to Roman MEDIUM

Length of Last Word EASY

Longest Common Prefix EASY

Reverse Words in a String MEDIUM

Zigzag Conversion MEDIUM

Find the Index of First Occurrence EASY

Text Justification HARD

Greedily pack words per line, then distribute spaces evenly (extra spaces go to the left gaps); last line is left-justified.

class Solution:
    def full_justify(self, words, max_width):
        res = []; line = []; length = 0
        for w in words:
            if length + len(line) + len(w) > max_width:
                slots = max(1, len(line) - 1)
                for i in range(max_width - length):
                    line[i % slots] += " "
                res.append("".join(line)); line = []; length = 0
            line.append(w); length += len(w)
        res.append(" ".join(line).ljust(max_width))
        return res

Two Pointers

Valid Palindrome EASY

Is Subsequence EASY

Two Sum II — Input Array Is Sorted MEDIUM

Container With Most Water MEDIUM

3Sum MEDIUM

Sort, fix one number, then two-pointer the rest. Skip duplicates. O(n²).

Sliding Window

Minimum Size Subarray Sum MEDIUM

Longest Substring Without Repeating Characters MEDIUM

Substring with Concatenation of All Words HARD

Minimum Window Substring HARD

Expand right to cover all needed chars, then shrink left while still valid. O(n).

Matrix

Valid Sudoku MEDIUM

Spiral Matrix MEDIUM

Pop the top row, rotate the rest counter-clockwise, repeat. O(m·n).

Rotate Image (90° in place) MEDIUM

Set Matrix Zeroes MEDIUM

Game of Life MEDIUM

Encode next state in bit 2 so neighbors still read the old state (bit 1), then shift. O(m·n), O(1) space.

Hashmap

Ransom Note EASY

Isomorphic Strings EASY

Word Pattern EASY

Valid Anagram EASY

Group Anagrams MEDIUM

Two Sum EASY

Happy Number EASY

Contains Duplicate II EASY

Longest Consecutive Sequence MEDIUM

Put all in a set; only start counting from numbers with no left neighbor. O(n).

Intervals

Summary Ranges EASY

Merge Intervals MEDIUM

Insert Interval MEDIUM

Min Number of Arrows to Burst Balloons MEDIUM

Sort by end, shoot at each non-overlapping end. Greedy. O(n log n).

Stack

Valid Parentheses EASY

Simplify Path MEDIUM

Min Stack MEDIUM

Evaluate Reverse Polish Notation MEDIUM

Basic Calculator HARD

Handle + - ( ). Push the running result & sign on (, fold back on ). O(n).

Linked List

Linked List Cycle EASY

Add Two Numbers MEDIUM

Merge Two Sorted Lists EASY

Copy List with Random Pointer MEDIUM

Map each old node to its clone, then wire up next/random. O(n).

Reverse Linked List II MEDIUM

Reverse Nodes in k-Group HARD

Remove Nth Node From End of List MEDIUM

Remove Duplicates from Sorted List II MEDIUM

Rotate List MEDIUM

Partition List MEDIUM

LRU Cache MEDIUM

An OrderedDict gives O(1) get/put with recency tracking (move_to_end).

Binary Tree — General

Maximum Depth of Binary Tree EASY

Same Tree EASY

Invert Binary Tree EASY

Symmetric Tree EASY

Construct Tree from Preorder & Inorder MEDIUM

First preorder value is the root; its index in inorder splits left/right. O(n).

Construct Tree from Inorder & Postorder MEDIUM

Populating Next Right Pointers II MEDIUM

Use the already-linked current level to build the next level's next chain. O(n), O(1) extra.

Flatten Binary Tree to Linked List MEDIUM

Path Sum EASY

Sum Root to Leaf Numbers MEDIUM

Binary Tree Maximum Path Sum HARD

Binary Search Tree Iterator MEDIUM

Count Complete Tree Nodes EASY

If left and right heights match, it's a perfect subtree → 2^h − 1. Otherwise recurse. O(log²n).

Lowest Common Ancestor of a Binary Tree MEDIUM

Binary Tree — BFS

Binary Tree Right Side View MEDIUM

Average of Levels in Binary Tree EASY

Binary Tree Level Order Traversal MEDIUM

Binary Tree Zigzag Level Order Traversal MEDIUM

Binary Search Tree

Minimum Absolute Difference in BST EASY

In-order visits values sorted → the min gap is between adjacent values. O(n).

Kth Smallest Element in a BST MEDIUM

Validate Binary Search Tree MEDIUM

Graph — General

Number of Islands MEDIUM

Surrounded Regions MEDIUM

Any 'O' connected to the border survives — mark those first, flip the rest. O(m·n).

Clone Graph MEDIUM

Evaluate Division MEDIUM

Build a weighted graph (a/b = v, b/a = 1/v); each query is a DFS multiplying edge weights.

Course Schedule (can finish?) MEDIUM

Detect a cycle in the prereq graph via 3-color DFS. O(V+E).

Course Schedule II (order) MEDIUM

Kahn's topological sort (BFS on in-degrees). O(V+E).

Graph — BFS

Snakes and Ladders MEDIUM

Minimum Genetic Mutation MEDIUM

Word Ladder HARD

Trie

Implement Trie (Prefix Tree) MEDIUM

Design Add and Search Words (wildcards) MEDIUM

Word Search II HARD

Put all words in a trie, then DFS the board once, pruning by trie paths.

Backtracking

Letter Combinations of a Phone Number MEDIUM

Combinations MEDIUM

Permutations MEDIUM

Combination Sum MEDIUM

N-Queens II (count) HARD

Generate Parentheses MEDIUM

Word Search MEDIUM

Divide & Conquer

Convert Sorted Array to BST EASY

Sort List (merge sort) MEDIUM

Construct Quad Tree MEDIUM

Merge k Sorted Lists HARD

Kadane's Algorithm

Maximum Subarray MEDIUM

Maximum Sum Circular Subarray MEDIUM

Answer is either a normal Kadane max, or total − (minimum subarray), whichever's bigger. Guard the all-negative case.

Binary Search

Search Insert Position EASY

Search a 2D Matrix MEDIUM

Treat the matrix as one sorted array of length rows·cols. O(log(mn)).

Find Peak Element MEDIUM

Search in Rotated Sorted Array MEDIUM

One half is always sorted — check which, then decide which side to keep. O(log n).

Find First and Last Position MEDIUM

Find Minimum in Rotated Sorted Array MEDIUM

Median of Two Sorted Arrays HARD

Binary-search a partition of the smaller array so left halves ≤ right halves. O(log(min(m,n))).

Heap

Kth Largest Element in an Array MEDIUM

IPO HARD

Greedy: among all affordable projects, always take the most profitable. Max-heap of profits. O(n log n).

Find K Pairs with Smallest Sums MEDIUM

Find Median from Data Stream HARD

Two heaps: a max-heap for the lower half, a min-heap for the upper. Median is the top(s). O(log n) per add.

Bit Manipulation

Add Binary EASY

Reverse Bits EASY

Number of 1 Bits EASY

Single Number EASY

Single Number II (others appear 3×) MEDIUM

Bitwise AND of Numbers Range MEDIUM

The result is the common binary prefix of left & right. Shift both right until equal. O(log n).

Math

Palindrome Number EASY

Plus One EASY

Factorial Trailing Zeroes MEDIUM

Count factors of 5 in n! (each pairs with a 2 to make a trailing zero). O(log n).

Sqrt(x) EASY

Pow(x, n) — fast exponentiation MEDIUM

Max Points on a Line HARD

1-D Dynamic Programming

Climbing Stairs EASY

House Robber MEDIUM

Word Break MEDIUM

Coin Change MEDIUM

Longest Increasing Subsequence MEDIUM

Patience sorting: keep the smallest tail for each length. O(n log n).

Multidimensional DP

Triangle MEDIUM

Minimum Path Sum MEDIUM

Unique Paths II (obstacles) MEDIUM

Longest Palindromic Substring MEDIUM

Expand around each center (odd and even length). O(n²).

Interleaving String MEDIUM

Edit Distance MEDIUM

Best Time to Buy and Sell Stock III (2 txns) HARD

Best Time to Buy and Sell Stock IV (k txns) HARD

Maximal Square MEDIUM

dp[r][c] = side of the largest all-1 square ending at (r,c) = 1 + min of its top/left/diagonal. O(m·n).

🗣️ Behavioral, projects & interview flow

Coding is only half the interview. A typical CS interview runs intro → resume/projects → coding → behavioral → your questions. These parts are free here because they win (or lose) you offers just as often as the algorithm does.

1. Intro & rapport2. Resume / projects3. Coding / technical4. Behavioral5. Your questions for them
Use STAR for every behavioral answer

Situation → Task → Action → Result. Set the scene in a sentence, say what you were responsible for, explain what you specifically did, then finish with a concrete (ideally measurable) result. Aim for ~90 seconds.

Resume & project questions
"Walk me through a project you built."
Pick one project and tell a story, not a feature list: the problem it solved, your key technical decisions and why, one hard bug or trade-off you hit, and the outcome (users, performance, what you'd improve). Interviewers care far more about your reasoning than the tech stack. Know your own code cold — they will drill into anything you claim.
Behavioral questions (with sample answers)
Tell me about a difficult team project.
S/T: On a class capstone our 4-person team fell behind because two members disagreed on the database design. A: I set up a 30-minute call, had each person whiteboard their approach, and we listed trade-offs in a shared doc; we chose the simpler schema and split the rest into clear tickets. R: We shipped on time and the grader praised our clean data model. Lesson: surfacing a disagreement early saves the whole team time.
Tell me about a conflict with a teammate.
Stay blameless and outcome-focused: "A teammate kept pushing directly to main, which broke our build. Instead of calling him out publicly, I asked to pair for ten minutes, showed how a quick PR + CI check avoids it, and proposed we protect the branch. He was on board, and our broken-build rate dropped to near zero." Show empathy + a process fix, never personal criticism.
Tell me about a time you failed or made a mistake.
Pick a real, low-stakes mistake and emphasize the lesson: "I once deployed a change without testing an edge case and it crashed for empty input. I rolled back, added a unit test for that case, and now I write the test first. It taught me that 'it works on my machine' isn't done." Owning it + a concrete habit change is exactly what they want.
How do you handle pressure / a tight deadline?
"I break the work into must-haves vs nice-to-haves, communicate early if scope is at risk, and protect a working version at every step. On a hackathon I cut a fancy feature to guarantee the core demo ran — we placed because it actually worked." Show prioritization and proactive communication, not heroics.
Tell me about learning a new technology quickly.
"I'd never used React, but a project needed it. I did the official tutorial, built a tiny throwaway app to cement the concepts, then leaned on docs + small experiments rather than copying blindly. Within a week I was productive." Show a repeatable learning process, not just 'I'm a fast learner.'
Explain a complex technical concept to a non-technical person.
Use an analogy and drop the jargon: "I explained an API as a waiter — you don't go into the kitchen, you give the waiter your order and they bring the food back. The API is the messenger between your app and the server." The skill being tested is empathy + clear communication.
How do you juggle multiple tasks?
"I list everything, rank by deadline and impact, time-box focused blocks, and re-check priorities daily. If two things truly collide, I ask my lead which matters more rather than guessing." Concrete system > "I'm good at multitasking."
Why do you want to work here?
Tie their mission/product to something specific about you: "You work on developer tools, and I've spent two years building side projects to make my own workflow faster — I want to do that for millions of engineers." Always research the company first; generic answers read as low effort.
How do you stay current with new tech and trends?
Show an active habit, not a list of podcasts: "I follow release notes and a couple of engineering blogs, but mostly I learn by building — when something looks useful I spin up a small project to try it. Recently I taught myself X that way." Demonstrating you learn by doing beats name-dropping resources.
When did you apply your skills to a business problem?
Connect code to measurable impact: "Support was drowning in repetitive tickets, so I wrote a script that auto-categorized them and surfaced the top issues. It cut triage time about 40% and let the team fix root causes instead of symptoms." Always link the tech to a business outcome.
Smart questions to ask THEM (have 2–3 ready)

"What does success look like in the first 90 days?" · "How does the team handle code review and testing?" · "What's the biggest technical challenge the team is facing right now?" · "How do you support growth for early-career engineers?" Asking nothing signals low interest — always ask at least two.

🎓 CS fundamentals — the questions interviewers actually ask

Crisp, correct answers to the conceptual questions that come up constantly (languages, OOP, memory/OS, databases, architecture & process). Free to read — tap any question.

Languages & execution
Compiler vs interpreter?
A compiler translates the whole program to machine code ahead of time, producing a standalone executable — fast to run, slower to build (C++, Go, Rust). An interpreter executes the source line-by-line at runtime — slower but flexible and easy to debug (Python). Hybrids (Java, C#) compile to bytecode, then a VM interprets/JIT-compiles it.
Statically vs dynamically typed languages?
Static typing checks types at compile time (Java, C++) — catches type errors early, more boilerplate. Dynamic typing checks at runtime (Python, JavaScript) — faster to write, but type errors surface later.
Object-oriented vs functional programming?
OOP organizes code around objects bundling state + behavior, emphasizing encapsulation, inheritance and polymorphism. Functional programming organizes around pure functions and immutable data, avoiding shared state and side effects. Most modern languages support both.
Character stream vs byte stream?
A byte stream reads/writes raw 8-bit bytes — use for binary data (images, files). A character stream reads/writes 16-bit characters with an encoding — better for text because it handles Unicode correctly. In Java: InputStream/OutputStream vs Reader/Writer.
Compiled vs interpreted language?
About a language's usual execution model. A compiled language is turned into native machine code before running (C, C++, Go) → fast execution, platform-specific binaries. An interpreted language is executed by an interpreter at runtime (Python, JavaScript, Ruby) → portable and quick to iterate, but slower. The line blurs: Java/C# compile to bytecode, then a VM runs (and JIT-compiles) it.
Object-oriented programming
What is a class? What is a superclass?
A class is a blueprint defining the data (fields) and behavior (methods) of a type of object — it encapsulates state and promotes reuse. A superclass is a parent/base class that another class (a subclass) inherits from; the subclass gets all the superclass's fields and methods and can add or override its own.
Overriding vs overloading?
Overriding: a subclass replaces an inherited method with its own implementation — same signature, resolved at runtime (polymorphism). Overloading: several methods share a name but have different parameter lists in the same class — resolved at compile time.
Pros and cons of multiple inheritance?
Pro: a class can combine behavior from several parents. Con: the "diamond problem" — ambiguity when two parents define the same method — plus extra complexity. That's why Java/C# forbid it for classes and use interfaces instead.
The SOLID principles?
Five OO design principles for maintainable code: Single-responsibility (one reason to change), Open/closed (open to extension, closed to modification), Liskov substitution (subtypes must be usable as their base), Interface segregation (many small interfaces > one fat one), Dependency inversion (depend on abstractions, not concretions).
Default vs conversion constructor?
A default constructor takes no arguments and sets default field values. A conversion constructor takes a single argument of another type and builds an object from it, enabling (often implicit) type conversion.
Memory & operating systems
What is garbage collection? How is memory managed?
Garbage collection automatically reclaims memory that's no longer reachable, so you don't free() manually (Java, Python, C#). The GC tracks references and frees unreachable objects; the trade-off is occasional pauses and less control. In manual languages (C/C++) you allocate (malloc/new) and must deallocate (free/delete) yourself, or you leak memory.
Primary vs secondary memory?
Primary (RAM) is fast, volatile main memory the CPU works from directly — contents are lost on power-off. Secondary (SSD, HDD, USB) is slower, non-volatile, far larger, and stores data permanently.
What is virtual memory?
An OS technique that gives each process its own large, contiguous address space by mapping it to physical RAM plus disk (paging). It lets programs use more memory than physically exists and isolates processes from one another.
What is a deadlock? How do you prevent it?
Two or more processes each hold a resource and wait for one the other holds, so none can proceed. Prevent it by breaking a Coffman condition — e.g. acquire locks in a consistent global order, use timeouts, or avoid hold-and-wait.
What is an operating system?
Software that manages hardware and resources and lets applications run — handling process scheduling, memory management, file systems and I/O. Common ones: Windows (compatibility), macOS (UX), Linux (servers, customizability).
Databases
What is normalization and why does it matter?
Organizing tables to cut redundancy and avoid update anomalies by splitting data into related tables (1NF → 2NF → 3NF…). It keeps data consistent and storage efficient; you JOIN tables when you need the combined view.
What is a transaction (ACID)?
A unit of work that must fully complete or fully roll back. ACID = Atomicity, Consistency, Isolation, Durability — guaranteeing reliable processing despite crashes or concurrent access.
Primary key vs foreign key?
A primary key uniquely identifies each row in a table. A foreign key is a column that references another table's primary key, enforcing a relationship and referential integrity between them.
What is a distributed database?
A database spread across multiple machines/locations that appears as one logical database. It improves scalability and availability but must handle replication, consistency and partition tolerance (the CAP trade-off).
Architecture, web & process
Monolith vs microservices?
A monolith is one deployable unit holding all features — simple to start, harder to scale and deploy piecemeal. Microservices split the app into small, independently deployable services talking over APIs — scalable and resilient, but more operational complexity.
What are CI and CD?
Continuous Integration = automatically build + test every change so issues surface early. Continuous Delivery/Deployment = automatically release those validated changes to staging/production, reducing risky manual releases.
What is DevOps?
A culture + practices uniting development and operations to ship faster and more reliably — automation, CI/CD, infrastructure-as-code, and continuous monitoring.
Waterfall vs Agile (and what is Scrum)?
Waterfall is sequential (requirements → design → build → test → release) — predictable, but inflexible to change. Agile is iterative: small increments in short cycles with continuous feedback, so you adapt and ship value sooner. Scrum is an Agile framework with 1–4-week sprints, daily standups, a prioritized backlog, and roles (Product Owner, Scrum Master, Dev Team).
Client-side vs server-side? SPA vs traditional?
Client-side code runs in the browser (HTML/CSS/JS) for interactivity; server-side runs on the server (Python/Java/Node) for data, auth and business logic. A SPA loads one page and updates content via JS/API calls without full reloads (app-like); a traditional multi-page app fetches a fresh page from the server per navigation.
Responsive design? Load balancing vs fault tolerance?
Responsive design adapts pages to any screen via fluid grids, flexible images and CSS media queries. Load balancing spreads requests across servers to avoid overload; fault tolerance keeps the system working when a component fails (redundancy/failover) — related but distinct goals.
Explain the Software Development Life Cycle (SDLC).
The process for building software end-to-end: requirements → design → implementation → testing → deployment → maintenance. Models include Waterfall (sequential) and Agile (iterative). It gives teams a structured, repeatable way to deliver quality software predictably.
Centralized vs decentralized system?
A centralized system has one controlling node/server everything depends on — simple, but a single point of failure. A decentralized system spreads control across many nodes with no single authority — more resilient and scalable, but harder to coordinate (e.g. peer-to-peer networks, blockchains).
Consensus algorithms in distributed systems?
They let many nodes agree on a single value/state despite failures or network delays. Protocols like Paxos and Raft elect a leader and replicate a log so all nodes stay consistent; blockchains use Proof-of-Work/Stake. They juggle consistency, availability and partition tolerance — the CAP theorem says you can't fully guarantee all three at once.
Algorithm concepts
Explain the idea behind dynamic programming.
Break a problem into overlapping sub-problems with optimal substructure, solve each once and store the result (memoization top-down, or tabulation bottom-up) to avoid recomputation. It turns exponential brute force into polynomial time — e.g. Fibonacci, knapsack, edit distance, LCS. (See the worked DP problems above.)
Time/space complexity of common data structures?
Array: index O(1), search O(n). Linked list: insert/delete at a known node O(1), search O(n). Balanced BST: search/insert/delete O(log n). Hash map: average O(1). Graph traversal (BFS/DFS): O(V+E). (Full table at the top of this page.)
How would you implement BFS (memory, queues, cycles)?
Use a queue: enqueue the start, then repeatedly dequeue a node, record it, and enqueue its unseen neighbors. Mark nodes seen at enqueue time (not dequeue) so a cyclic graph never re-adds a node. Time O(V+E), space O(V). See the Java implementation below.
Shortest path in a weighted graph?
For non-negative weights use Dijkstra's algorithm: keep a min-heap of (distance, node), repeatedly pop the closest unvisited node and relax its edges (update neighbor distances). O((V+E) log V). For graphs with negative weights use Bellman-Ford; for an unweighted graph plain BFS already gives the shortest path. (Dijkstra skeleton is in the Code templates section.)
~190 classic problems + the top 150 interview questions — original Python, Big-O & difficulty tags, the 25 pattern templates, complexity tables, and the 7-stage interview playbook. One of the most complete free interview references anywhere. Bookmark it and good luck! 🍀