Skip to content

LeetCode Interview Prep

Progress

On LeetCode ->

LeetCode Top Easy

(17 days) 2026-04-06 -> 2026-04-22

Problems [48/48]

LeetCode Top Easy ->

——— Array ———

——— Strings ———

——— Linked List ———

——— Trees ———

——— Sorting and Searching ———

——— Dynamic Programming ———

——— Design ———

——— Math ———

——— Others ———

Lessons

2026-04-07

  • Read the questions and conditions carefully.
  • Find the solution on paper. If you don't find it on paper, odds are you won't implement it correctly on a computer.
  • Find the trick. There's always one. When you find it, the solution becomes simple and classic.

2026-04-11

  • Draw.
    • Try different visual representations.
    • They help you see and find patterns.
    • They help you think about the right data structures to use.
  • Run the algorithm by hand with visuals and small values.
  • Re-state or reformulate the problem.

2026-04-14

  • Check your tests. When they fail, maybe some test cases are wrong and your implementation is right.
  • Check your helpers. Make sure the helpers you use in your tests to build data structures like lists, trees, ... are correct. Your tests may be failing because those helpers are wrong.

2026-04-15

  • Group or isolate elements. When you're reasoning about a "set" of something—it can be a tuple, list, set, tree, ...—change the way you look at it. You can look at its elements one by one, or see them as subsets. For instance, if x = [1, 2, 3, 4, 5], you can look at 1, or any other element, or look at it like this: x = [A | B] where A = [1, 2] and B = [3, 4, 5]. See problem 189. Rotate Array for instance.

2026-04-19

  • Learn the trick. Sometimes the solution, especially because of time and space constraints, uses a property of the system or a specific algorithm you've never seen before. Chances are you won't find it in limited time. That's ok. Don't take it personally. After trying your best, just learn the trick and add it to your toolkit. For instance, in 136. Single Number, you can get a program with \(O(1)\) space by keeping in mind the equalities a ^ a = 0 and a ^ 0 = a for any integer a, and the fact that XOR is commutative and associative.
  • Never forget you're doing an interview. A solution for an interview must please the interviewer and show what the interviewer expects, not the most idiomatic solution. For example, in 125. Valid Palindrome, don't use a regex pattern match on a string when a two-pointer solution that traverses the string as an array is expected.
  • Never rush or try to go fast. Find the flow. You'll be at your maximum speed, and the problem will solve itself.

2026-04-20

  • Take advantage of the constraints. Most of the time, constraints affect the program at the edges: empty list, starting with at least one node in a tree, ruling out negative values, ... But sometimes, they let you choose a totally different approach or algorithm. See problem 326. Power of Three for instance, where testing whether \(n\) is a power of \(3\) becomes testing whether \(n\) divides \(3^{19}\), the largest power of \(3\) smaller than \(2^{31} - 1\), the upper bound of the constraint.

2026-04-25

  • Recognize the pattern. It's only possible to do this after you've seen a pattern at least once. Practice more, and you'll have more patterns in your toolkit. Simple.

2026-07-02

  • Start sentences with precise verbs when describing algorithms. For instance:
Feedback

You usually reach a correct solution and test it well, but often use more machinery than needed. You should focus now in recognizing patterns before coding.

What are your main strengths?

  1. You persist until you find a correct solution.
  2. You test edge cases and revise effectively.
  3. You write clean code once you recognize the pattern.

What are your weaknesses?

  1. You simulate problems instead of first searching for a simple invariant.
  2. You sometimes overlook time, space, overflow, or in-place requirements.
  3. You add unnecessary state, helpers, and custom traversal logic.

What best thinking process could you adopt to solve these problems faster?

  1. Before coding, identify the problem family and the strongest constraint.
  2. State what must remain true throughout the algorithm.
  3. Keep only the variables needed to preserve that property, then test boundary cases.

Leetcode Google Interview

(6 days) 2026-05-25 -> 2026-05-30

Problems [17/17]

LeetCode Random Questions ->

——— LeetCode Random Questions ———

Lessons

2026-05-26

  • Use a stack. If you need to process in reverse order of consumption, use a stack. See 445. Add Two Numbers II.
  • Use a queue. If you need to process in same order of consumption, use a queue.

2026-05-27

  • Think fast. Fail fast. And solve the problem.
  • Don't fall into the trap. Sometimes problems are not what they seem to be. For instance, 290. Word Pattern looks like a simple string parsing, but is in fact a small hash map problem. Likewise, 542. 01 Matrix looks like DP, but the clean solution is really a graph shortest path from many sources at once.
  • Reverse the search. For instance, in 542. 01 Matrix, the problem is framed like this "return the distance of the nearest 0 for each cell". But the right way to look at it is to reverse the search and start from 0 nodes and expand one layer at a time until reaching 1s of non processed nodes yet, which gives the shortest distances.

2026-05-28

  • Don't confuse linear time with one pass. 2 passes is still linear time: \(O(2n) = O(n)\). See 229. Majority Element II.

2026-06-01

  • Write simple and correct code fast. Sometimes this means using built-ins like in 929. Unique Email Adresses where using split and replace string methods makes the code easy to follow. Remember that in interviews, "better" usually means:
    • correct
    • easy to explain
    • easy to verify
    • hard to break
    • written quickly

2026-06-02

  • Don't forget to advance while loops. For instance:
    • while i < n: ... expects i += 1 in while block.
    • while left < right: ... expects left += 1 or right -= 1 or both in the while block.
    • while stack: ... expects stack.pop() in the while block.
    • while queue: ... expects queue.popleft() in the while block.
    • while tail: ... expects tail = tail.next in the while block, assuming tail has the property next to advance the list.
Feedback

You recognize more problem families and adopt standard solutions faster than in LeetCode Top Easy. However, you still start coding before making the invariant and boundaries precise.

What are your main strengths?

  1. You identify the correct algorithm family more often.
  2. You use Python data structures comfortably.
  3. You learn from feedback and rewrite solutions quickly.

What are your weaknesses?

  1. You still simulate a process when a simpler summary would work.
  2. You sometimes miss standard templates such as sliding window or multi-source BFS.
  3. You make boundary and update errors when variable meanings are unclear.

What best thinking process could you adopt to solve these problems faster?

  1. Describe the task as a familiar operation, such as finding a boundary or maintaining a valid window.
  2. Define what every variable and data structure represents before updating it.
  3. Use a standard template and test the beginning, end, smallest input, and repeated values.

LeetCode Top Medium

(58 days) 2026-06-05 -> 2026-08-01

Problems [45/45]

LeetCode Top Medium ->

——— Array and Strings ———

——— Linked List ———

——— Trees and Graphs ———

——— Backtracking ———

——— Sorting and Searching ———

——— Dynamic Programming ———

——— Design ———

——— Math ———

——— Others ———

Lessons

2026-06-07

  • Find a canonical representation. When you're dealing with a class of objects defined by some constraints, look for a canonical representation of that class, preferably one that's hashable.
    • For instance, all anagrams have the same sorted-letter representation, and so we can use it as a key to group strings by anagrams. See 49. Group Anagrams.
    • Another example: in 36. Valid Sudoku we pick (r // 3) * 3 + (c // 3) as the box id, a canonical way to represent belonging to one of the 3x3 boxes in a Sudoku grid.

2026-06-08

  • Store the index, not only the value. When you find an element in a Python list (array), you have its index, its positions. So you can move a pointer to this position in \(O(1)\) later without rescanning the array. You must take advantage of this property of Python list. For instance, in 3. Longest Substring Without Repeating Characters, storing the indices along the characters of the characters you scan in the list lets you move the left pointer of the sliding window in \(O(1)\).

  • Build a list of parts and join them to make a string. When iteratively building a string, prefer to build a list of the parts and join them after the loop is finished. It's more efficient than concatenating strings while iterating. See 38. Count and Say for instance.

2026-06-11

  • Find the minimal state your program needs to take its next action at any time.

2026-06-12

  • Mark visited nodes within the input data. This is \(O(1)\) space contrary to \(O(n)\) if using a different global set, dictionary, matrix, etc.
    • For instance, in 200. Number of Islands, we can mark visited cell by sinking land into water like this grid[r][c] = "0", so that we don't count the same island twice.
    • For instance, in 79. Word Search, we can mark the cell board[r][c] = "#" (and storing its value in ch variable) so that we don't consider that cell again for the path we're building. And when we backtrack to build another path, we restore its value board[r][c] = ch to make it available for the new path.

2026-06-23

  • Don't enumerate. In LeetCode problems, only in rare cases you'll be asked to enumerate explicitly. But if you think about path enumaration, tuple enumaration, etc. to solve the problem, you're almost always going in the wrong direction. There's is an invariant about the problem, an approach you haven't seen yet. Find it. Enumeration has really bad time complexity. For instance in 55. Jump Game, exploring every possible paths to find one that reaches the end of the array is useless and time expensive. Keeping the maximum reachable index at each step while scanning the array is enough.

2026-06-25

  • Don't be lazy. When you have an idea for solving part of the problem: 1) validate it or 2) discard it. Never leave it unclassified just because you're too lazy to give it a shot. For instance, while trying to solve 380. Insert Delete GetRandom O(1):
    • I had the idea that I would need a list of the values, and a map from value to index, for the GetRandom operation. But I didn't really try to see how it could be implemented.
    • While implementing a solution after reading AI comments, I saw that I had to remove values from the list in \(O(1)\). But I didn't think enough to have a chance to find the simple solution: swap with the last value in the list, then pop the list.

2026-07-17

  • Generate permutations in-place. When dealing with permutations, for each index, swap it with any element in the rest of the list (including at itself). See 384. Shuffle an Array (random permutations) and 46. Permutations. Remember that the permutation group is generated by all transpositions, that is, swaps between pairs.
Feedback

Your mathematical modeling and edge-case analysis improved from LeetCode Google Interview. Your main remaining issue is reducing a valid idea to the smallest sufficient state before implementation.

What are your main strengths?

  1. You often find useful equations, recurrences, keys, or pointer relationships.
  2. You use edge cases and counterexamples effectively.
  3. You explain your reasoning clearly and revise incorrect assumptions.

What are your weaknesses?

  1. You track many possibilities when one summary value would suffice.
  2. You detect hidden complexity and mutation risks too late.
  3. You sometimes solve the basic task but miss its required complexity or mutation rules.

What best thinking process could you adopt to solve these problems faster?

  1. Extract the exact output, mutation, time, and space requirements before choosing an algorithm.
  2. Identify repeated work and replace it with a boundary, count, lookup, or best-so-far value.
  3. State the invariant, use its standard template, and test cases designed to break it.

LeetCode Top Hard

(24 days) 2026-08-02 -> 2026-08-25

Problems [46/46]

LeetCode Top Hard ->

——— Array and Strings ———

——— Linked List ———

——— Trees and Graphs ———

——— Backtracking ———

——— Sorting and Searching ———

——— Dynamic Programming ———

——— Design ———

——— Math ———

——— Others ———

Lessons

2026-08-02

2026-08-23

  • Find the invariants. Find where the answer live, in which space. For instance in 41. First Missing Positive noticing that the answer must be in \([1, n + 1]\) opens a new way to look at the problem, which leads to the algo proposed. I didn't notice this.
Feedback

You identify the right algorithm family more consistently than in LeetCode Top Medium and build stronger initial models. Your remaining gap is selecting and proving the exact invariant instead of forcing a familiar technique.

What are your main strengths?

  1. You recognize BFS, DP, greedy, heaps, and two-pointer problems quickly.
  2. You use counterexamples to expose flawed assumptions.
  3. You build reasonable baseline solutions and optimize them effectively.

What are your weaknesses?

  1. You sometimes choose the right algorithm family but the wrong state or invariant.
  2. You preserve too much state and repeat avoidable work.
  3. You sometimes discard candidates, mutate state, or ignore duplicates without proving it is safe.

What best thinking process could you adopt to solve these problems faster?

  1. Write the brute-force complexity and identify the exact work that must be eliminated.
  2. Define the smallest state that still preserves every detail needed for correctness.
  3. Before each pointer move, discard, or mutation, explain why no valid answer can be lost.

LeetCode Graph Theory

(11 days) 2026-09-06 -> 2026-09-16

Problems [28/28]

LeetCode Graph Theory ->

Problems already solved in another collections have been removed.

——— Standard Traversal ———

——— BFS ———

——— Matrix Graphs ———

——— Graph Theory ———

——— Union Find / DSU ———

——— Topological Sort ———

——— Dijkstra's (subscribers) ———

——— Minimum Spanning Tree (subscribers) ———

Lessons

2026-09-10

  • Check your code for silly mistakes before submitting it.

2026-09-12

  • Be confident in your solution. When a problem seems trivial, maybe it is for you now. You practice consistently, so it's normal that what was hard one day becomes easy another day. It can feel surprising at first, but you should notice that you've improved, then just crush the problem and move on. For instance, I found the correct solution, with proof and implementation, almost instantly for 1557. Minimum Number of Vertices to Reach All Nodesproblem, which is said to be of medium difficulty. It was so easy and so quick that I thought there had to be a trap I missed.
Feedback

Your graph modeling and standard traversals are stronger than in the previous batch . Your main risk now is defining too little search state or losing track of what each update means.

What are your main strengths?

  1. You recognize reachability, shortest paths, components, and dependencies.
  2. You find useful reductions, such as reverse searches and boundary flood fills.
  3. You use BFS and DFS reliably on straightforward problems.

What are your weaknesses?

  1. You sometimes mark a node as visited when its color, keys, or DFS status also matter.
  2. You lose the invariant in small updates, such as changing the wrong node or counting an edge twice.
  3. You repeat path searches when one reverse traversal or topological pass could combine the work.

What best thinking process could you adopt to solve these problems faster?

  1. Name the graph task, then define exactly what a queue entry and a visited state represent.
  2. Before searching from many starting points, check whether you can reverse the search or combine sources.
  3. Trace one transition: what you read, update, and enqueue. Then test a cycle and a converging path.

LeetCode Dynamic Programming

(9 days) 2026-09-17 -> 2026-09-25

Problems [34/34]

LeetCode Dynamic Programming ->

Problems already solved in another collections have been removed.

——— Fibonacci style ———

——— Matrix ———

——— On Strings ———

——— Longest Increasing Subsequence ———

——— Longest Common Subsequence ———

——— Best Time to Buy & Sell Stock / State Machine ———

——— On Trees ———

——— Knapsack ———

——— General 1D ———

Lessons

No Lessons.

Feedback

Compared with the previous batch, you show stronger instincts for reusable states and reducing memory in DP. You recognize the right problem shape, but sometimes compress the state before proving that it preserves every possible winning path.

What are your main strengths?

  1. You recognize grid, subsequence, knapsack, and stock DP patterns.
  2. You look for reusable states and ways to reduce memory.
  3. You notice when sorting or greedy choices would destroy important order.

What are your weaknesses?

  1. You sometimes keep only one history when another could lead to a better answer later.
  2. You compress DP too early, causing update-order and boundary errors.
  3. You sometimes leave counting rules and complexity checks until after choosing the loops.

What best thinking process could you adopt to solve these problems faster?

  1. Define exactly what each state represents, then ask whether two histories with that state can have different futures.
  2. Write every legal transition and derive the base cases before filling the table.
  3. Check the full DP's complexity first; compress it only after you can explain what each value means before and after an update.

LeetCode Design

(?? days) 2026-09-27 -> ??

Design [52/126]

LeetCode Design ->

Problems already solved in another collections have been removed.

——— Simple state and simulation ———

——— Hash maps and indexed state ———

——— Randomized arrays ———

——— Stacks, queues, and linked structures ———

——— Iterators and lazy traversal ———

——— Streaming counters and sliding windows ———

——— Range queries and updates ———

——— Time-indexed and versioned state ———

——— Heaps, rankings, and order statistics ———

——— Tries and prefix search ———

——— Encoding and serialization ———

——— Trees and hierarchical structures ———

——— Intervals and reservations ———

——— Ordered buckets and eviction caches ———

——— Graph-backed services ———

——— Composite event and marketplace systems ———

Lessons

2026-09-27

  • Don't forget self when designing classes.
    • Use self.my_func(...) and self.my_attr when calling methods or referring to attributes.
    • Use self as the first argument when defining methods: def my_func(self, ...).

2026-09-29

  • Ask the interviewer for clarification. LeetCode design problem descriptions are vague.
    • Constraints may not be fully specified and may only become clear from the examples: For instance in 2408. Design SQL, column IDs are 1-based, but you can only deduced that constraint by reading precisely the first example.
    • Constraints may be understood in more than one way: In 2590. Design a Todo List, I didn't understand that the task IDs must be incremented globally across users, not per user "This ID starts at 1 and is sequentially increasing.". The example didn't help with this as it only add task to one user.
Feedback

TODO

LeetCode SQL 50

(?? days) 2026-07-07 -> 2026-...

Problems [35/50]

LeetCode SQL 50 ->

——— Select ———

——— Basic Joins ———

——— Basic Aggregate Functions ———

——— Sorting and Grouping ———

——— Advanced Select and Joins ———

——— Subqueries ———

——— Advanced String Functions / Regex / Clause ———

Lessons

2026-07-13

  • Manage your energy. If you're tired after solving a problem in SQL, take a break and come back fresh to solve it in Pandas. Don't look up the answer before really trying to solve it yourself. You never learn anything that way.

2026-07-14

  • Don't use reserved keywords in SQL queries. For instance, in 1661. Average Time of Process per Machine, I tried to use End as a CTE table name, and it errored. When I changed it to EndActivity, it worked fine. This was likely because of the SQL syntax CASE ... END.