avatar
Wang,ZetianZetianNotes

My study notes

This is my study note.

LeetCode Study Notes: 360 Medium and Hard Problems

360 questions: 270 Medium + 90 Hard, grouped by coding pattern.

Practice order ​

  • P1: core patterns. Start here.
  • P2: variations that build on P1.
  • P3: advanced problems and combined patterns.

For each question, write a solution, test edge cases, and explain its time and space complexity. Check it off when you can solve it again without hints. Premium marks questions that require paid access.

Questions ​

1. Hashing, prefix sums and arrays — 27 ​

2. Two pointers and sliding windows — 23 ​

3. Strings, parsing and stacks — 19 ​

4. Monotonic stacks and ordered sequences — 11 ​

5. Binary search and answer-space search — 20 ​

6. Linked lists — 11 ​

7. Trees and BSTs — 32 ​

8. Heaps, selection and scheduling — 17 ​

9. Intervals, sweep lines and greedy proofs — 26 ​

10. Backtracking and constraint search — 22 ​

11. Tries and prefix matching — 10 ​

12. Graph traversal, topology and connectivity — 35 ​

13. Weighted graphs and advanced state search — 19 ​

14. Dynamic programming: state, choices and knapsack — 43 ​

15. Dynamic programming: advanced composition — 16 ​

16. Design, range structures, math and bit invariants — 29 ​

Python coding patterns ​

Prefix sums + frequency map ​

Use for counting subarrays with a target sum (LC 560). Count earlier prefixes before inserting the current one. O(n) time and O(n) space.

python
def subarray_sum(nums, k):
    frequency = {0: 1}
    prefix = answer = 0
    for value in nums:
        prefix += value
        answer += frequency.get(prefix - k, 0)
        frequency[prefix] = frequency.get(prefix, 0) + 1
    return answer

Sliding window ​

Use for a longest substring with no repeated characters (LC 3). Move the left boundary past the previous occurrence. O(n) time and O(u) space for u distinct characters.

python
def longest_unique_substring(s):
    last_seen = {}
    left = answer = 0
    for right, char in enumerate(s):
        left = max(left, last_seen.get(char, -1) + 1)
        last_seen[char] = right
        answer = max(answer, right - left + 1)
    return answer

Binary search: lower bound ​

Find the first index whose value is at least target in a sorted array (a building block for LC 34). Return len(nums) if no such index exists. Keep the search interval [left, right). O(log n) time and O(1) space.

python
def lower_bound(nums, target):
    left, right = 0, len(nums)
    while left < right:
        mid = (left + right) // 2
        if nums[mid] < target:
            left = mid + 1
        else:
            right = mid
    return left

BFS: shortest unweighted path ​

Use for graphs with equal-cost edges. Mark nodes when enqueuing so each node enters the queue once. graph[node] contains its neighbors. O(V + E) time and O(V) space.

python
from collections import deque


def shortest_distance(graph, start, target):
    queue = deque([(start, 0)])
    seen = {start}
    while queue:
        node, distance = queue.popleft()
        if node == target:
            return distance
        for neighbor in graph.get(node, []):
            if neighbor not in seen:
                seen.add(neighbor)
                queue.append((neighbor, distance + 1))
    return -1

Dynamic programming: take or skip ​

Use for non-adjacent selection (LC 198). Track the best total before the previous house and through the previous house. For nonnegative house values: O(n) time and O(1) space.

python
def house_robber(nums):
    previous_two = previous_one = 0
    for value in nums:
        previous_two, previous_one = (
            previous_one,
            max(previous_one, previous_two + value),
        )
    return previous_one
KafkaBasic