Leetcode
Lộ trình phát triển toàn diện Leetcode theo tiêu chuẩn quốc tế nilbuild/developer-roadmap
Hướng dẫn từng bước từ nền tảng đến chuyên sâu giúp bạn làm chủ Leetcode. Tích hợp tài liệu lý thuyết, bài viết thực chiến, video tham khảo và bài tập lập trình trực tiếp trên IDE.
Nền Tảng & Khái Niệm Cốt Lõi
Giai đoạn 1 tập trung hoàn thiện 31 chủ đề then chốt.
1-D Dynamic Programming
Dynamic programming is the technique of breaking a problem into overlapping subproblems, solving each once, and storing the result to avoid recomputation. In one-dimensional DP, each state depends only on a fixed number of previous states, so the solution builds a single array from left to right. The first step is always identifying the recurrence: what does the answer at position i depend on? The problems here cover the core DP patterns you will see repeatedly: linear sequences, knapsack decisions, and string segmentation. DP problems are notoriously hard to recognize, and the only reliable way to get better at them is to solve many and study the structure of their recurrences.
2-D Dynamic Programming
Two-dimensional DP extends the same ideas to problems where the state depends on two variables simultaneously, typically two indices into two sequences or two dimensions of a grid. The table is now a matrix, and each cell is filled based on cells above it, to its left, or diagonally adjacent. The problems here include string comparison (edit distance, longest common subsequence), grid path counting, and interval DP where you think about ranges rather than prefixes. These problems tend to be harder to set up than 1-D DP, but once you identify the state and the transition, the code follows directly from the recurrence.
3Sum
Given an array of integers, find all unique triplets that sum to zero. You sort the array first, then for each element use two pointers to find pairs that complete the triplet. The sort plus two pointers bring it from O(n³) to O(n²). This problem teaches you to extend the two pointer technique beyond pairs and introduces how sorting enables smarter traversal.
Advanced Graphs
Advanced graph problems involve weighted edges, which require more sophisticated algorithms than simple BFS or DFS. Dijkstra's algorithm finds the shortest path in a weighted graph using a min-heap. Prim's and Kruskal's algorithms find the minimum spanning tree, connecting all nodes at minimum total cost. These algorithms are more complex than anything seen so far, and the problems here often combine the algorithm with an additional constraint, such as a limit on the number of steps or a non-standard cost function. Understanding the conditions under which each algorithm applies is as important as knowing how to implement it.
Arrays & Hashing
Arrays and hash maps are the building blocks of almost every algorithm problem. Before learning any pattern, you need to be comfortable navigating an array and reaching for a hash map when you need fast lookups. Most problems in this stage are solved in one or two passes, and the main skill you are developing is recognizing when a hash map can replace a nested loop. If you find yourself thinking about checking membership or counting frequencies, a hash map is almost always the right tool.
Backtracking
Backtracking is a systematic way to explore all possible solutions by making a choice, recursing, and undoing the choice when you backtrack. It is the right tool for problems that ask for all combinations, all permutations, all subsets, or any valid configuration. The key skill is recognizing when to prune: stopping a branch early when you can tell it cannot lead to a valid solution. Without pruning, backtracking is just brute force. Most problems here share the same recursive skeleton and differ only in the constraints that determine valid choices and stopping conditions.
Best Time to Buy and Sell Stock
Given an array of daily stock prices, find the maximum profit from one buy and one sell. You track the minimum price seen so far and the best profit achievable at each step using a single pass. This is the simplest sliding window problem since the window always expands from the current day, and it teaches you how to track a running minimum and maximum simultaneously.
Binary Search
Given a sorted array and a target, return the index of the target or -1 if not found. You repeatedly halve the search space by comparing the middle element to the target. This is the simplest form of binary search and the one you must be able to write without mistakes before moving to harder variants.
Binary Search
Binary search is not just for finding an element in a sorted array. It is a general technique for eliminating half the search space at each step, and it applies whenever you can define a condition that splits possible answers into a valid half and an invalid half. The problems in this stage move from the textbook version to more creative applications: searching in rotated arrays, and binary searching on the answer itself rather than on the input. Getting binary search right under pressure, with correct boundary conditions, is a skill that requires deliberate practice.
Binary Tree Level Order Traversal
Given a binary tree, return its node values level by level. You use a queue to process all nodes at one level before moving to the next, collecting each level into its own list. This is the entry point for tree BFS and teaches you the queue-based level tracking pattern that applies to many tree and graph problems.
Binary Tree Maximum Path Sum
Given a binary tree where nodes can have negative values, find the maximum sum of any path between any two nodes. At each node you decide whether to extend either child's path or start fresh, tracking the global maximum as you go. This is one of the hardest tree DFS problems and teaches you to separate what you return up the recursion from what you record as your answer.
Bit Manipulation
Bit manipulation uses the binary representation of integers directly through bitwise operators: AND, OR, XOR, and shifts. It is useful for problems involving pairs, uniqueness, flags, or any situation where you need to extract or toggle individual bits. XOR is particularly powerful because it is its own inverse: XOR-ing a value twice cancels out. The problems here are mostly short, but they require a different way of thinking about numbers. Once you internalize the basic bit operations, you will start seeing where they can replace more expensive data structures in problems across other categories.
Burst Balloons
Given an array of balloons with values, burst all of them to maximize coins, where bursting a balloon gives coins equal to the product of itself and its neighbors. You use interval DP: instead of choosing which balloon to burst first, you choose which to burst last within each interval. This problem teaches you that sometimes reversing the order of decisions makes the DP structure cleaner.
C++
C++ is the language of choice for competitive programmers and is common in companies where raw performance matters, such as systems, gaming, or high-frequency trading. It has the fastest execution time of any commonly used interview language and gives you direct access to the standard template library, which includes a heap, set, map, and many other useful structures. The tradeoff is verbosity and the overhead of managing memory manually in some cases. If you are already proficient in C++, it is an excellent interview language. If you are starting from scratch, the learning curve is steep.
Longest Repeating Character Replacement
Given a string and a number k, find the length of the longest substring where you can replace at most k characters to make all characters the same. You track the count of the most frequent character in the window, and if the window size minus that count exceeds k, you shrink from the left. This problem teaches you a clever invariant: you never need to shrink the window below its maximum size seen so far.
Cheapest Flights Within K Stops
Given a graph of flights with prices, find the cheapest route from source to destination using at most k stops. This is a modified Dijkstra or Bellman-Ford problem where the constraint is on the number of edges, not just total cost. This problem teaches you how to add an extra dimension (number of steps) to a shortest path algorithm.
Climbing Stairs
You can climb one or two steps at a time. Find the number of distinct ways to reach the top of n stairs. The number of ways to reach step n is the sum of ways to reach n-1 and n-2, which is exactly the Fibonacci pattern. This is the entry point to DP and teaches you to see a problem as a recurrence: the answer at each state depends on previous states.
Clone Graph
Given a connected undirected graph, return a deep copy of it. You use DFS or BFS and a hash map to track which nodes have already been cloned, so you do not create duplicate copies when revisiting nodes. This problem teaches you to handle graphs with cycles during traversal, which requires tracking visited nodes from the start.
Coin Change
Given coin denominations and a target amount, find the minimum number of coins needed. You build a DP table where each amount stores the fewest coins to make it, using each coin to update future amounts. This is the canonical unbounded knapsack problem and teaches you bottom-up DP where you iterate over amounts rather than items.
Combination Sum
Given an array of distinct integers and a target, return all unique combinations that sum to the target, where each number can be used unlimited times. You use backtracking, and at each step either reuse the current number or move to the next. This problem teaches you how to allow repetition in backtracking by staying at the same index instead of advancing.
Container With Most Water
Given an array of bar heights, find two bars that together with the x-axis form a container holding the most water. You start with the widest possible container and move the pointer on the shorter side inward, since that is the only move that could increase the area. This problem teaches the key insight that moving the longer side never helps, which is a non-obvious greedy choice that the two pointer pattern makes visible.
Contains Duplicate
Given an array, return true if any value appears more than once. The brute force compares every pair, but a hash set lets you check for duplicates in a single pass. Simple as it sounds, this problem is your first introduction to using a set for O(1) membership checks, a pattern you will see in almost every stage.
Counting Bits
Given an integer n, return an array where each element is the number of 1 bits in its binary representation from 0 to n. You can use DP: the number of bits in i equals one plus the bits in i with its lowest set bit removed. This problem teaches you to combine bit manipulation with DP to avoid recomputing from scratch for each number.
Course Schedule
Given a list of courses and prerequisites, determine if it is possible to finish all courses. This is a cycle detection problem in a directed graph: if any cycle exists, the schedule is impossible. You can solve it with DFS by tracking nodes in the current recursion path. This problem teaches you topological sort thinking and is a gateway to all dependency-based graph problems.
Daily Temperatures
Given an array of daily temperatures, return an array where each element is the number of days until a warmer temperature. A monotonic stack stores indices of temperatures in decreasing order, and whenever a warmer day is found, all colder days in the stack get their answer. This problem is the entry point for the monotonic stack pattern, which appears in many harder problems.
Design Add and Search Words Data Structure
Build a data structure that supports adding words and searching for words where a dot can match any letter. Exact characters navigate the trie normally, while a dot triggers DFS across all child nodes. This problem teaches you how to combine trie traversal with backtracking for wildcard matching.
Edit Distance
Given two strings, find the minimum number of insertions, deletions, or replacements to transform one into the other. A 2D DP table tracks the cost to convert each prefix of one string to each prefix of the other. This problem teaches you the three-way choice at each cell (insert, delete, replace) and is a foundational example of DP on two sequences.
Find Median from Data Stream
Design a data structure that supports adding numbers one by one and returning the median at any point. You maintain two heaps: a max-heap for the lower half and a min-heap for the upper half, keeping them balanced so the median is always accessible at the top. This is the defining two-heap problem and teaches you how splitting a dataset into two heaps gives O(log n) insertion and O(1) median retrieval.
Gas Station
Given gas amounts and costs at each station on a circular route, find the starting station from which you can complete the circuit. If total gas is at least total cost, a solution exists, and the starting point is always after the last segment where the running tank went negative. This problem teaches you that a global observation (total gas vs total cost) can determine existence, while a local scan finds the answer.
Generate Parentheses
Given n, generate all combinations of well-formed parentheses. You build strings recursively, adding an opening bracket if you still have some left and a closing bracket only if it would not break validity. This problem sits at the boundary between stack and backtracking thinking and teaches you to use constraints to prune the search space before exploring it.
Go
Go is a statically typed, compiled language designed for simplicity and performance. It is increasingly popular in backend and infrastructure roles and is commonly used at companies like Uber, Cloudflare, and Docker. Its syntax is minimal, and its concurrency model is distinctive, but for LeetCode purposes, what matters is its straightforward standard library and fast execution. Go does not have a built-in generic data structure library as rich as Java or C++, so you will sometimes need to implement things like heaps from scratch using the container/heap interface. It is a good choice if Go is your day-to-day language.
Kỹ Năng Trọng Tâm & Thực Hành
Giai đoạn 2 tập trung hoàn thiện 31 chủ đề then chốt.
Graphs
Graphs generalize trees by allowing arbitrary connections and cycles. The two core traversal techniques, DFS and BFS, work on graphs the same way they do on trees, but you must now track visited nodes explicitly to avoid infinite loops. This stage covers the main graph problem types: counting connected components, detecting cycles, finding shortest paths in unweighted graphs, and topological ordering of dependencies. Grids are also implicit graphs, where each cell is a node and adjacency is defined by its four neighbors. Most graph problems reduce to one of these patterns once you recognize the structure.
Greedy
Greedy algorithms make the locally optimal choice at each step and never revisit decisions. They are faster and simpler than DP when they work, but proving that a greedy choice leads to a globally optimal solution is not always obvious. The problems in this stage cover the most common greedy patterns: interval scheduling, jump games, and character frequency problems. A useful habit is to first ask whether a greedy approach is correct before coding it: can a short-sighted choice ever lead you away from the best solution? If the answer is yes, you probably need DP instead.
Group Anagrams
Given a list of strings, group together all strings that are anagrams of each other. Since anagrams share the same characters, sorting each string gives a common key you can use in a hash map. A more optimal approach uses character frequency arrays as keys instead of sorting. This problem teaches you to think about what makes two things equivalent and use that equivalence as a grouping key, a useful mental model for many hash map problems.
Happy Number
A happy number is one that eventually reaches 1 when you repeatedly replace it with the sum of the squares of its digits. Detect whether a number is happy. This is a cycle detection problem: if the process loops without reaching 1, the number is not happy. You can use Floyd's algorithm or a set to detect the cycle. This problem teaches you to recognize cycle detection in non-graph contexts.
Heaps and Priority Queue
A heap is the right data structure when you repeatedly need the largest or smallest element from a changing collection. The problems in this stage cover three heap patterns: top-k elements (maintain a heap of size k), two heaps (split a dataset into two halves to track the median), and k-way merge (combine multiple sorted sequences using a single heap). If you find yourself wanting to sort something repeatedly as new elements arrive, a heap is almost always the better choice. Getting comfortable with heap operations and knowing which variant to reach for is the main skill this stage develops.
House Robber
You are a robber planning to steal from houses in a row. You cannot rob two adjacent houses. Find the maximum amount you can steal. At each house you choose to rob it and skip the previous, or skip it and keep the best from before. This problem teaches the classic DP choice between taking the current element and combining it with a past state, or skipping it.
Implement Trie
Build a trie data structure that supports inserting a word, searching for an exact word, and checking if any word starts with a given prefix. Each node stores a map of child characters and a flag marking word endings. This problem teaches you the trie structure itself, which is prerequisite knowledge for all harder trie problems.
Insert Interval
Given a sorted list of non-overlapping intervals and a new interval, insert it and merge any overlaps. You add all intervals that end before the new one starts, merge all that overlap with it, then add the rest. This problem teaches you to handle three distinct regions when inserting into a sorted interval list, a pattern that requires careful boundary thinking.
Intervals
Interval problems appear frequently in scheduling, calendar, and range-based questions. The dominant technique is sorting by start or end time, which turns an otherwise quadratic overlap-checking problem into a linear scan. Once sorted, you can merge overlaps, count simultaneous events, or find gaps with a single pass. The harder problems in this stage combine interval sorting with a heap to answer queries efficiently. The key mindset shift is thinking of intervals as objects with a start and end, and reasoning about what it means for two intervals to overlap, contain, or be adjacent.
Java
Java is one of the most commonly used interview languages, especially at large companies with backend and enterprise codebases. Its type system is verbose but explicit, and the standard library is comprehensive with well-documented data structures including priority queues, linked lists, and tree maps. Java forces you to think about types and interfaces clearly, which can actually help structure your thinking on harder problems. The main downside for interview prep is boilerplate: simple operations require more lines than in Python or Ruby. If Java is your primary language, it is a strong and widely accepted choice.
JavaScript
JavaScript is a solid choice if you already use it professionally or are preparing for frontend-focused roles. Its array methods and object literals are expressive, and most algorithmic patterns translate naturally to it. The main limitation is that JavaScript lacks a built-in heap or priority queue, so you will need to implement one or use a library when heap problems arise. If you are comfortable with JavaScript and do not want to switch languages just for interviews, it is a perfectly valid choice.
Jump Game II
Given the same setup, find the minimum number of jumps to reach the last index. You greedily track the end of the current jump range and the furthest you can reach within it, incrementing the jump count when you exhaust the current range. This problem teaches you the two-range greedy technique, where you separate the current jump's boundary from the next one. Visit the question on the LeetCode [website](https://leetcode.com/problems/jump-game-ii/).
Jump Game
Given an array where each element is the maximum jump length from that position, determine if you can reach the last index. You track the furthest position reachable so far and update it at each step. This problem teaches you the core greedy insight: you never need to track which specific jumps you take, only how far you can reach.
K Closest Points to Origin
Given a list of points, return the k closest to the origin. A max-heap of size k keeps the k smallest distances seen so far, ejecting any point farther than the current kth closest as you iterate. This problem shows how to adapt the top-k pattern to a custom comparison and is good practice for heap problems with custom keys.
Koko Eating Bananas
Koko can eat at most k bananas per hour and must finish all piles within h hours. Find the minimum k. The answer lies in a range, and you can binary search on that range, checking for each candidate k whether it is feasible. This problem teaches you to binary search on the answer rather than on the input array, a shift in thinking that unlocks many harder problems.
Kth Largest Element in an Array
Given an unsorted array and an integer k, return the kth largest element. You can use a min-heap of size k: iterate through the array, push each element, and pop when the heap exceeds k. The top of the heap is then the kth largest. This problem teaches the core heap pattern: maintain a fixed-size heap to track top-k elements without sorting the entire array.
Largest Rectangle in Histogram
Given an array of bar heights, find the area of the largest rectangle that fits in the histogram. A monotonic stack tracks bars in increasing order of height, and each time a shorter bar is encountered, rectangles extending from the previous bars are resolved. This is one of the hardest stack problems and teaches you to use a stack to resolve pending computations when a condition breaks.
Linked List Cycle
Given the head of a linked list, determine if it contains a cycle. The fast and slow pointer technique has one pointer move one step at a time and the other move two steps at a time; if there is a cycle, they will eventually meet. This problem introduces the fast-and-slow-pointer pattern, which is used in several more advanced linked list problems.
Linked List
Linked list problems test your ability to manipulate pointers directly, without the convenience of index-based access. The core techniques are the dummy node (to simplify edge cases at the head), the fast and slow pointer (to find midpoints and detect cycles), and in-place reversal (to rearrange nodes without extra memory). These three techniques cover the majority of linked list problems. The problems here also build the pointer intuition you will need when working with trees in the next stage.
Longest Common Prefix
Given an array of strings, find the longest common prefix among all of them. One approach inserts all strings into a trie and traverses down as long as each node has exactly one child and is not a word end. This problem is simpler than the others but it teaches you that tries are not only for search, they also encode shared structure between strings.
Longest Common Subsequence
Given two strings, find the length of their longest common subsequence. If characters match, you extend the LCS from the diagonal; otherwise you take the best from dropping one character in either string. This is the canonical 2D DP problem and teaches you how a 2D table captures the relationship between two sequences simultaneously.
Longest Increasing Subsequence
Given an array, find the length of the longest strictly increasing subsequence. For each element, you check all previous elements that are smaller and extend the best subsequence ending there. This problem teaches you patience sorting and the classic O(n²) DP formulation, with an O(n log n) binary search optimization as a natural follow-up.
Lowest Common Ancestor of a BST
Given a BST and two nodes, find their lowest common ancestor. Because it is a BST, you can use the values to decide whether to go left, right, or stop: the ancestor is where the two nodes diverge. This problem teaches you to exploit BST ordering as a navigation tool, rather than doing a general tree search.
Math and Geometry
Math and geometry problems test your ability to translate a visual or numerical pattern into clean algorithmic logic. Many of these problems have elegant solutions that depend on a single mathematical observation, such as the structure of matrix rotation or the periodicity of digit sums. Unlike the earlier stages, there is no dominant pattern here. Instead, you are developing the habit of looking for structure in a problem before reaching for a general algorithm. These problems are a good test of problem-solving maturity: can you find the insight, or do you default to brute force?
Maximum Depth of Binary Tree
Given a binary tree, return its maximum depth, meaning the number of nodes along the longest root-to-leaf path. You recursively compute the depth of left and right subtrees and return one plus the greater. This is the simplest tree DFS problem and teaches you to think about trees recursively: a tree's depth is defined in terms of its subtrees' depths.
Median of Two Sorted Arrays
Given two sorted arrays, find the median of their combined elements in O(log(min(m, n))). You binary search on the smaller array to find a partition where all elements on the left side are smaller than all on the right. This is one of the hardest binary search problems and teaches you to think about partitioning rather than searching for a single value.
Meeting Rooms
Given a list of meeting time intervals, determine if a person can attend all of them. You sort by start time and check if any meeting starts before the previous one ends. This is the simplest interval problem and teaches you that sorted order plus a single-pass scan resolves most interval overlap questions instantly.
Merge Intervals
Given a list of intervals, merge all overlapping ones. You sort by start time and iterate, extending the current interval when the next one overlaps, or starting a new one when it does not. This is the foundational interval problem and teaches you that sorting by start time reduces the overlap check to a single comparison with the previous interval's end.
Merge K Sorted Lists
Given k sorted linked lists, merge them into one sorted list using a min-heap. You insert the head of each list into the heap, then repeatedly extract the minimum and push the next node from that list. This problem sits at the intersection of heaps and linked lists and is the canonical k-way merge example.
Merge K Sorted Lists
Given k sorted linked lists, merge them into one sorted list. The optimal approach uses a min-heap to always extract the smallest current node across all lists. This problem connects linked list manipulation with heap usage and is the defining example of the k-way merge pattern.
Merge Two Sorted Lists
Given the heads of two sorted linked lists, merge them into one sorted list by splicing nodes together without creating new ones. You compare the heads of both lists at each step and attach the smaller node to your result. This problem teaches you the dummy node technique, which simplifies edge cases when building a new list from scratch.
Kiến Trúc Nâng Cao & Tối Ưu
Giai đoạn 3 tập trung hoàn thiện 31 chủ đề then chốt.
Min Cost to Connect All Points
Given a list of points, find the minimum cost to connect all of them, where cost is the Manhattan distance between two points. This is a minimum spanning tree problem solvable with Prim's algorithm using a min-heap, always picking the cheapest edge to an unvisited node.
Minimum Interval to Include Each Query
Given a list of intervals and queries, for each query find the length of the smallest interval that contains it. You sort both intervals and queries, use a min-heap keyed by interval length, and process queries in order. This is the hardest interval problem in this stage and teaches you the offline query technique, processing queries in sorted order alongside a heap.
Min Stack
Design a stack that supports push, pop, top, and retrieving the minimum element, all in O(1) time. The trick is to maintain a second stack that tracks the current minimum at each level. This problem teaches you that stacks can be augmented to carry extra state without breaking their core behavior.
Find Minimum in Rotated Sorted Array
Given a rotated sorted array, find the minimum element in O(log n). The minimum is always at the rotation point, and you can locate it by checking which half is sorted and narrowing toward the unsorted side. This problem teaches you to think about what binary search is really doing: eliminating halves, not just finding a value.
Minimum Window Substring
Given strings s and t, find the smallest substring of s that contains all characters of t. You expand the right pointer until you have a valid window, then shrink from the left as much as possible while keeping it valid. This is one of the hardest sliding window problems and teaches you to manage a character frequency map as the window changes.
More Exercises
Below you can find other popular questions covering Math and Geometry. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Binary Search. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Heap and Priority Queue. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Sliding Window. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Bit Manipulation. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering 1-D Dynamic Programming. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Backtracking. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Advanced Graphs. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Arrays & Hashing. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Greedy. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering 2-D Dynamic Programming. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Two Pointers. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Intervals. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Graphs. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Linked List. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Stack. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Trees. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Tries. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Math and Geometry. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Binary Search. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Heap and Priority Queue. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Sliding Window. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Bit Manipulation. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering 1-D Dynamic Programming. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Backtracking. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Advanced Graphs. Work through these once you are comfortable with the five above.
Hệ Sinh Thái & Triển Khai Thực Tế
Giai đoạn 4 tập trung hoàn thiện 31 chủ đề then chốt.
More Exercises
Below you can find other popular questions covering Arrays & Hashing. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Greedy. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering 2-D Dynamic Programming. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Two Pointers. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Intervals. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Graphs. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Linked List. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Stack. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Trees. Work through these once you are comfortable with the five above.
More Exercises
Below you can find other popular questions covering Tries. Work through these once you are comfortable with the five above.
N-Queens
Place n queens on an n by n chessboard so that no two queens attack each other, and return all valid configurations. You place queens row by row and use sets to track which columns and diagonals are occupied, backtracking when a row has no valid placement. This is the classic constraint satisfaction problem and teaches you to use auxiliary state to prune the search space aggressively.
Network Delay Time
Given a network of nodes and weighted directed edges, find the time it takes for a signal to reach all nodes from a source. This is Dijkstra's algorithm: you use a min-heap to always process the closest unvisited node next. This problem teaches you Dijkstra's algorithm in its clearest form, without extra complications, making it the best starting point for weighted shortest path problems.
Non-overlapping Intervals
Given a list of intervals, find the minimum number to remove so that no two intervals overlap. Sorting by end time and greedily keeping non-conflicting intervals gives the maximum number you can keep, and the answer is total minus that. This problem reinforces the greedy interval scheduling principle and connects directly to the activity selection problem in algorithm theory.
Non-overlapping Intervals
Given a list of intervals, find the minimum number of intervals to remove so that the rest do not overlap. You sort by end time and greedily keep every interval that does not conflict with the last kept one. This problem teaches the classic interval scheduling insight: always prefer the interval that ends earliest, since it leaves the most room for future intervals.
Number of 1 Bits
Given a 32-bit integer, count how many bits are set to 1. You can check the last bit with a bitwise AND and shift right repeatedly, or use the trick n & (n-1) which clears the lowest set bit, counting until n becomes zero. This problem teaches you to inspect and clear individual bits, a fundamental bit manipulation skill.
Number of Islands
Given a 2D grid of land and water cells, count the number of islands. You do DFS from each unvisited land cell, marking the entire connected landmass as visited before moving on. This is the entry point for graph DFS on a matrix and teaches you to treat a grid as an implicit graph where adjacency is defined by up, down, left, right neighbors.
Pacific Atlantic Water Flow
Given a matrix of heights, find all cells from which water can flow to both the Pacific and Atlantic oceans. You reverse the problem: do BFS inward from each ocean's border, marking all reachable cells, then return cells reachable from both. This problem teaches you that reversing the direction of traversal can turn an exponential problem into a linear one.
Partition Labels
Given a string, partition it into as many parts as possible so that each letter appears in at most one part. You find the last occurrence of each character first, then greedily extend the current partition's boundary as you scan. This problem teaches you how to greedily build non-overlapping intervals using the last-occurrence anchor, a pattern that appears in several interval problems.
Permutations
Given an array of distinct integers, return all possible orderings. Unlike subsets, order matters here, so at each step you pick any unused element and continue recursively. This problem teaches you the difference between combination-style and permutation-style backtracking, and how to track which elements have been used.
Pick a language
For LeetCode and technical interviews, the language you use matters less than how well you know it. Pick one language and stick with it throughout your preparation. Switching between languages wastes time and splits your focus. What interviewers care about is whether you can write clean, correct code and explain your reasoning clearly. That said, some languages have practical advantages: Python is concise and fast to write, which is helpful under time pressure. Java and C++ are common in companies that care about performance. JavaScript is a natural choice if you are coming from frontend development.
Pow(x, n)
Implement the power function that raises x to the nth power, including negative exponents, in O(log n). You use fast exponentiation: square the base and halve the exponent at each step, handling odd exponents by multiplying in an extra factor. This problem teaches you recursive divide-and-conquer on a numerical computation, and is the standard way to implement exponentiation efficiently. Visit the question on the LeetCode [website](https://leetcode.com/problems/powx-n/).
Python
Python is the most popular language for LeetCode preparation and for good reason. Its syntax is concise, its built-in data structures like lists, dictionaries, and sets map directly to the structures you use in almost every problem, and the standard library includes a heap module and collections utilities that save significant time. Writing a sliding window or a DFS in Python requires far fewer lines than in most other languages. If you do not have a strong preference, Python is the recommended default for this roadmap.
Reconstruct Itinerary
Given a list of airline tickets, reconstruct the itinerary in lexical order starting from JFK, using all tickets exactly once. You use DFS with a sorted adjacency list and add nodes to the result only after all their outgoing edges are exhausted, which is Hierholzer's algorithm for Eulerian paths. This problem teaches you a non-obvious graph traversal where the order of adding nodes to the result is reversed.
Regular Expression Matching
Given a string and a pattern with dot and star wildcards, determine if the pattern matches the entire string. A 2D DP table tracks whether each prefix of the string matches each prefix of the pattern, with special handling for the star operator. This is one of the hardest 2D DP problems and teaches you to handle optional repetition in DP, where a character can appear zero or more times.
Reorder List
Given a linked list, reorder it so that nodes alternate from the front and back of the original list. You find the middle, reverse the second half, then merge the two halves. This problem combines three sub-techniques (finding middle, reversing, merging) and teaches you to decompose complex pointer problems into simpler steps.
Replace Words
Given a dictionary of root words and a sentence, replace each word in the sentence with its shortest matching root from the dictionary. You insert all roots into a trie, then for each word in the sentence traverse the trie character by character until you hit a root or fail. This problem teaches you practical trie lookup with early termination, which is the core of trie efficiency.
Reverse Bits
Given a 32-bit unsigned integer, reverse its bits. You build the result bit by bit by extracting the last bit from the input and shifting it into the result. This problem teaches you how to construct a new number bit by bit using shifts and masks, which is useful in many low-level and embedded contexts.
Reverse Linked List
Given the head of a linked list, reverse it in place and return the new head. You iterate through the list, keeping track of the previous node, current node, and next node, rewiring each pointer as you go. This is the first linked list problem most people learn and it teaches you the three-pointer technique that underlies almost every in-place list manipulation.
Rotate Image
Given an n by n matrix, rotate it 90 degrees clockwise in place. You first transpose the matrix (swap across the diagonal), then reverse each row. This problem teaches you that complex in-place transformations often decompose into two simpler operations applied in sequence.
Ruby
Ruby is an expressive, readable language with clean syntax and strong built-in enumerable methods that make array and hash manipulation concise. It is less common in technical interviews than Python, JavaScript, or Java, but it is a valid choice if you use it professionally and are comfortable with it. One practical consideration is that Ruby solutions on LeetCode are sometimes slower than equivalent solutions in compiled languages, which can occasionally cause timeout issues on harder problems. Use Ruby if it is your strongest language, but be aware of this limitation.
Rust
Rust is a systems programming language focused on memory safety and performance without a garbage collector. It is gaining popularity for roles in systems programming, WebAssembly, and performance-critical applications. For LeetCode, Rust is the most challenging language to use due to its strict ownership model, which can make pointer-heavy problems like linked lists and trees significantly more complex to implement than in other languages. If you are already comfortable with Rust and want to use it for interviews, it is possible and impressive, but it is not recommended as a starting point for interview preparation.
Chuyên Gia & Mở Rộng Hệ Thống
Giai đoạn 5 tập trung hoàn thiện 31 chủ đề then chốt.
C
C is a general-purpose, procedural programming language that provides low-level access to system memory and efficient mapping to machine instructions. It is known for its minimalist design, which relies on a simple set of keywords and a straightforward syntax to perform tasks. C remains a foundational language for building operating systems, embedded systems, and high-performance applications where execution speed and resource efficiency are critical.
Search in Rotated Sorted Array
A sorted array has been rotated at an unknown index. Find a target value in O(log n). At every step, one of the two halves must be sorted, and you can use that to decide which half to search. This problem teaches you to apply binary search even when the input is not perfectly sorted, by adding a condition to identify the sorted half.
Serialize and Deserialize Binary Tree
Design an algorithm to convert a binary tree to a string and reconstruct it exactly from that string. One approach uses BFS level-order, encoding null pointers explicitly so the structure can be recovered. This problem teaches you that tree traversal is not just for reading trees but also for encoding and rebuilding them, a fundamental idea in tree design problems.
Set Matrix Zeroes
Given a matrix, if any cell is zero, set its entire row and column to zero, in place. The trick is to record which rows and columns need zeroing before making any changes, using the first row and column as markers to avoid extra space. This problem teaches you to use existing space within the matrix to avoid allocating extra memory, a useful in-place technique.
Single Number
Given an array where every element appears twice except one, find the element that appears only once. XOR of a number with itself is zero, and XOR of a number with zero is the number itself, so XOR-ing all elements cancels duplicates and leaves the unique one. This problem is the entry point to bit manipulation and teaches you that XOR is a surprisingly powerful tool for finding missing or unique values.
Sliding Window Maximum
Given an array and a window size k, return the maximum value in each window. A monotonic deque stores indices in decreasing order of value, so the front is always the current maximum. This problem teaches you the monotonic deque, which gives O(n) window max where a heap would give O(n log n).
Sliding Window
The sliding window pattern is used when you need to find an optimal subarray or substring that satisfies some constraint. Instead of checking every possible subarray from scratch, you maintain a window with two pointers and update the result incrementally as the window expands or shrinks. Fixed-size windows are straightforward; variable-size windows require a clear rule for when to shrink from the left. This stage also introduces the monotonic deque, which extends sliding window to problems that need the maximum or minimum within the window at each step.
Spiral Matrix
Given an m by n matrix, return all elements in spiral order. You maintain four boundaries (top, bottom, left, right) and peel one layer at a time, moving right, down, left, then up, shrinking the boundaries after each direction. This problem teaches careful boundary management and is a good test of whether you can translate a visual pattern into clean code.
Stacks
A stack is the right tool whenever you need to process elements in a last-in-first-out order, or when you need to track something that will be resolved later. Many stack problems involve matching pairs, maintaining a running minimum or maximum, or deferring a computation until a future element triggers it. The monotonic stack variant, where you maintain elements in increasing or decreasing order, is particularly important and appears frequently in harder problems involving histograms, temperatures, and next greater elements.
Subsets
Given an array of unique integers, return all possible subsets, including the empty set. You use backtracking to make a binary decision at each element: include it or skip it, building subsets recursively. This problem teaches the foundation of backtracking, the include/exclude decision tree that underpins all subset and combination problems.
Longest Substring Without Repeating Characters
Find the length of the longest substring that contains no duplicate characters. You expand the right pointer and shrink the left pointer whenever a duplicate enters the window, using a set to track current characters. This is the canonical variable-size sliding window problem and teaches you the expand-then-shrink rhythm that most substring problems follow.
Sum of Two Integers
Calculate the sum of two integers without using the plus or minus operators. XOR gives the sum without carries, and AND shifted left gives the carries. You repeat until there are no more carries. This problem teaches you how addition works at the bit level and deepens your understanding of carry propagation.
Swim in Rising Water
Given a grid where each cell has a height, find the earliest time t such that you can travel from top-left to bottom-right, moving only through cells with height at most t. You binary search on t or use Dijkstra treating each cell's height as the cost. This problem teaches you to reframe a graph problem as a min-max path problem, where you minimize the maximum cost along any path.
Task Scheduler
Given a list of tasks and a cooldown n, find the minimum time needed to finish all tasks, with the constraint that the same task must wait n intervals between executions. A greedy approach with a max-heap always schedules the most frequent remaining task, filling cooldown gaps with other tasks or idle time. This problem teaches you to combine a heap with a greedy scheduling strategy.
Top K Frequent Elements
Given an array and a number k, return the k most frequent elements. You could sort by frequency, but the optimal approach uses bucket sort. Since no element can appear more times than the length of the array, you can create buckets indexed by frequency and scan from the top. This problem bridges hash maps and sorting, and introduces the idea that the constraints of a problem often suggest a faster algorithm.
Trapping Rain Water
Given an array of bar heights representing an elevation map, compute how much water can be trapped between the bars after rain. For each position, the water level is determined by the shorter of the tallest bars to its left and right. Two pointers eliminate the need to precompute these maximums separately. This is one of the hardest two-pointer problems and teaches you to reason about what constrains a value from both directions.
Trees
Trees are the data structure where recursion becomes natural. Most tree problems follow DFS, going deep before backtracking, or BFS, processing level by level. DFS is usually recursive and suits path-based problems, while BFS uses a queue and suits level-based or shortest-path questions. A key habit is separating what a function returns from what it records as a side effect, since many problems need a global answer tracked alongside local recursive decisions. Segment trees and Fenwick trees extend these ideas to range queries over a mutable array, though they show up more in competitive programming than standard interviews.
Tries
A trie is a tree structure built from the characters of strings, where each path from the root to a marked node spells out a word. It is the right data structure when you need fast prefix lookups across a large set of strings. A hash map can check if a whole word exists, but a trie can check if any word in your dictionary starts with a given prefix in O(length) time. The three problems in this stage cover building a trie, searching with wildcards, and using a trie to prune a grid search, which together cover the full range of trie applications in interviews.
Two Pointers
Two pointers is the first real pattern you will learn, and it is one of the most reusable. The idea is simple: instead of checking every pair of elements with nested loops, you place one pointer at each end of a sorted structure and move them toward each other based on a condition. This brings many O(n²) problems down to O(n). Most problems here require a sorted input, so sorting is often the first step. Mastering this pattern also prepares you for fast and slow pointers, which appear in linked list problems later.
Two Sum II
Given a sorted array, find two numbers that add up to a target and return their positions. Because the array is sorted, you can use two pointers starting from each end and move them based on whether the current sum is too large or too small. This is where the two pointer pattern clicks for most learners, since the sorted order gives a clear rule for which pointer to move.
Two Sum
You are given an array of integers and a target number. The goal is to find two numbers in the array that add up to the target and return their positions. The naive approach checks every pair, but the key insight is using a hash map to store numbers you have already seen, bringing the solution from O(n²) down to O(n). This problem teaches the core habit of trading space for time, a trade-off you will use constantly in harder problems.
Unique Paths
A robot starts at the top-left of an m by n grid and can only move right or down. Find the number of unique paths to the bottom-right. Each cell's count is the sum of the cell above and the cell to the left. This is the simplest 2D DP problem and teaches you to think in terms of a grid where each cell builds on its neighbors.
Valid Anagram
Given two strings, decide if one is an anagram of the other, meaning both contain the exact same characters with the same frequency. The trick is not to sort (which works but is slower), but to count character frequencies using a hash map and compare them. This problem teaches you to think about strings as frequency distributions rather than sequences of characters.
Valid Palindrome
Given a string, determine if it reads the same forward and backwards after removing non-alphanumeric characters and ignoring case. Two pointers start at each end and move inward, comparing characters as they go. This problem teaches you to use two pointers on a string and is a clean entry point for understanding how pointers can replace nested loops.
Valid Parentheses
Given a string of brackets, determine if it is valid, meaning every opening bracket is closed by the same type in the correct order. You push opening brackets onto a stack and pop when you see a closing bracket, checking for a match. This is the canonical stack problem and teaches you the key idea: a stack naturally tracks things that need a future match.
What are coding patterns?
Coding patterns are recurring problem-solving strategies that apply across many different problems. Instead of memorizing solutions, you learn to recognize the structure of a problem and match it to a pattern you already know. Once you internalize around fifteen to twenty patterns, you can approach most interview problems with a starting point rather than a blank page. This roadmap is organized around those patterns.
What is LeetCode
LeetCode is an online platform with hundreds of coding problems used by software engineers to prepare for technical interviews. Companies like Google, Meta, Amazon, and Microsoft use similar problems in their hiring process to evaluate how candidates think through algorithmic challenges. You do not need to solve thousands of problems to be ready. What matters is understanding the patterns behind problems well enough to apply them to ones you have never seen before. LeetCode is the practice ground, not the goal.
Word Break
Given a string and a dictionary of words, determine if the string can be segmented into a sequence of dictionary words. You use DP where each position stores whether the substring up to that point can be formed, checking every possible last word. This problem teaches you how to use a boolean DP array to track reachability, a pattern that appears in many string segmentation problems.
Word Ladder
Given a start word and an end word, find the shortest transformation sequence where each step changes exactly one letter and every intermediate word must exist in a given word list. BFS gives the shortest path, and each word's neighbors are found by replacing each character with every letter. This is the hardest graph problem in this stage and teaches you to model an abstract problem as a shortest-path graph problem.
Word Search II
Given a board of characters and a list of words, return all words that exist in the board. You build a trie from the word list and do DFS from each cell, pruning paths that do not match any trie prefix. This problem is the hardest trie problem in this stage and teaches you how a trie dramatically reduces the search space compared to checking each word separately.
Word Search
Given a 2D grid of characters and a word, determine if the word exists in the grid by following adjacent cells. You do DFS from each cell that matches the first character, marking visited cells to avoid reuse in the current path. This problem teaches you backtracking on a 2D grid, where you must undo your visited marks when a path fails.