Introduction
Site Utility
This site helps you develop a structured and templated way of thinking to solve algorithm problems. No matter your current skill level, this site can help you quickly reach a score of 85 out of 100.
Because the site teaches a templated and structured thinking mode, the 85 score you achieve is consistent and not dependent on luck. In other words, for problems with difficulty less than 85, you will definitely solve them. For problems with difficulty greater than 85, success might depend on inspiration and luck.
What does a score of 85 mean?
For comparison, let's assume you are a computer science major, have taken required data structures and algorithms courses, and primarily use various development frameworks in your job but have never practiced algorithm problems. Your level might be around 30-40 out of 100. It's true because algorithm skills can be seen as a separate ability that isn't directly related to programming experience and requires dedicated practice.
So don't think a score of 85 is low; this level is more than sufficient for technical job interviews and exams. Also, don't be afraid of algorithms. By using the right methods and dedicating some time to practicing problems, it's easy to improve your algorithm skills.
About This Site
Stay updated with the latest address of this site: labuladong.online.
This site supports both mobile and PC reading. For mobile users, it's recommended to open it directly in WeChat for easy one-click login.
This site provides a framework-based approach to guide you through solving over 500 LeetCode/力扣 problems. The algorithmic thinking you develop here will remain sharp, enabling you to quickly regain problem-solving skills even years later.
You can use the magnifying glass icon at the top right of the site to search its content, with support for directly searching by LeetCode/力扣 problem names, numbers, and links in both English and Chinese.
The site is continuously updated and optimized, with access to the "Update Log" and "Bug Feedback" at the top.
Site Structure
Introduction
Preparation: LeetCode Practice Kit
Chrome Extension for LeetCode vscode Plugin for LeetCode JetBrains Plugin for LeetCode Algorithm Visualization Introduction Subscribe to this Algo Notes
Quick Start: Data Structures and Sorting
Prerequisites for LeetCode
Implement Dynamic Arrays
Implement Single/Double Linked List
Implement Queue and Stack
Implement HashMap
Hash Table Variations
Binary Tree Structure and Traversal
Binary Tree Variations
Graph Theory and Traversals
Implement and Visualize 10 Sorting Algorithms
Key Metrics of Sorting Algorithms Explore Selection Sort in Depth Bubble Sort with Stability Insertion Sort with Reverse Thinking Shell Sort - Better than O(N^2) Quick Sort and Binary Tree Preorder Merge Sort and Binary Tree Postorder Heap Sort and Binary Heap Counting Sort: A New Pespective on Sorting Bucket Sort Radix Sort
Updating
Chapter 0. Classic Problem Solving Templates
Chapter Introduction How to Think About Data Structure and Algorithm Two Pointer Techniques for Linked List Problems Two Pointer Techniques for Array Problems Sliding Window Algorithm Code Template Binary Search Algorithm Code Template Dynamic Programming Common Patterns and Code Template Backtracking Algorithm Common Patterns and Code Template BFS Algorithm Common Patterns and Code Template Thinking Recursion Algorithms from Binary Tree Perspective Backtracking Algorithm to Solve All Permutation/Combination/Subset Problems Time and Space Complexity Analysis Practical Guide
Chapter 1. Data Structure Algorithms
Linked List
Array
Two Pointer Techniques for Array Problems Tricks to Traverse a 2D Array One Trick to Solve All N-Sum Problems Exercise: Two Pointer Techniques for Array Prefix Sum Array Technique Exercise: Prefix Sum Techniques Difference Array Technique Sliding Window Algorithm Code Template Exercise: Sliding Window In Action Sliding Window Application: Rabin Karp String Matching Algorithm Binary Search Algorithm Code Template Binary Search in Action Exercise: Binary Search Algorithm Weighted Random Selection Algorithm Advantage Shuffle Algorithm
Binary Tree
Thinking Recursion Algorithms from Binary Tree Perspective Binary Tree in Action (Traversal) Binary Tree in Action (Construction) Binary Tree in Action (Post-order) Binary Tree in Action (Serialization) Binary Search Tree in Action (In-order) Binary Search Tree in Action (Basic Operations) Binary Search Tree in Action (Construction) Binary Search Tree in Action (Post-order)
In Action: Solve 100 Binary Tree Problems
Exercise: Binary Tree Traversal I Exercise: Binary Tree Traversal II Exercise: Binary Tree Traversal III Exercise: Binary Tree Divide and Conquer I Exercise: Binary Tree Divide and Conquer II Exercise: Binary Tree Combine Two Views Exercise: Binary Tree Post-order I Exercise: Binary Tree Post-order II Exercise: Binary Tree Post-order III Exercise: Binary Tree Level I Exercise: Binary Tree Level II Exercise: Binary Search Tree I Exercise: Binary Search Tree II
Binary Tree Follow-up
Design Data Structures
Implement Stack with Queue, Implement Queue with Stack Exercise: Stack Problems on LeetCode Exercise: Bracket Problems on LeetCode Exercise: Queue Problems on LeetCode Monotonic Stack Code Template Exercise: Monotonic Stack Problems on LeetCode Monotonic Queue to Solve Sliding Window Problems Exercise: Monotonic Queue Implementation and Leetcode Problems Implementing LRU Cache like Building a Lego Implementing LFU Cache like Building a Lego How to Deleting Array Element in O(1) Time Exercise: Hash Table Problems on LeetCode Exercise: Priority Queue Problems on LeetCode Implementing TreeMap/TreeSet Implementing Trie/Digtal Tree/Prefix Tree Exercise: Trie Problems on LeetCode Designing a Twitter Feed Designing an Exam Room Algorithm Exercise: Classic Design Problems on LeetCode How to Implement a Calculator Implementing Median Algorithm with Two Binary Heaps Removing Duplicates from an Array (Hard Version)
Graph
Chapter 2. Brute Force Search
DFS and Backtracking Algorithm
Backtracking Algorithm Common Patterns and Code Template Backtracking Algorithm to Solve All Permutation/Combination/Subset Problems Ball and Box: Two Perspectives of Backtracking Enumeration Some Questions About Backtracking and DFS Algorithms Solve All Island Problems with DFS Backtracking Algorithm Practice: Solving Sudoku Backtracking Algorithm Practice: Generating Valid Parentheses Backtracking Algorithm Practice: Partitioning k Subsets Exercise: Backtracking Problems on LeetCode I Exercise: Backtracking Problems on LeetCode II Exercise: Backtracking Problems on LeetCode III
BFS Algorithm
Chapter 3. Dynamic Programming Algorithms
Basic DP Techniques
Dynamic Programming Common Patterns and Code Template How to Design Transition Equations How to Determine the Base Case and Initial Values for Memoization? Two Perspectives of Dynamic Programming Enumeration How to Convert Backtracking to Dynamic Programming Optimize Space Complexity for Dynamic Programming Clarifying Some Questions About Dynamic Programming
Subsequence Problems
Knapsack Problems
Dynamic Programming Game
Classic DP: Minimum Path Sum Play Dungeon Game with DP Play Freedom Trail with DP Save Money on Your Trip: Weighted Shortest Path Classic DP: Regular Expression Matching Classic DP: Egg Drop Classic DP: Burst Balloons Classic DP: Game Theory One Method to Solve All House Robber Problems on LeetCode One Method to Solve all Stock Problems on LeetCode
Greedy
Chapter 4. Other Common Techniques
Mathematical Techniques
LeetCode Problems with One Line Solution Common Bit Manipulation Techniques Random Algorithms in Games Two Classic Factorial Problems on LeetCode How to Efficiently Count Prime Numbers How to Efficiently Perform Modular Exponentiation How to Find Missing and Duplicate Elements Interesting Probability Problems Exercises: Math Tricks
Classic Interview Problems
Tips for Algorithmic Exams How to Efficiently Solve the Trapping Rain Water Problem One Article to Solve All Ugly Number Problems on LeetCode Divide and Conquer Algorithm: Operator Precedence One Method to Solve Three Interval Problems on LeetCode Split Array into Consecutive Subsequences Pancake Sorting Algorithm String Multiplication Calculation How to Determine if a Rectangle is Perfect
Appendix
Expired URLs/PDFs/Content
As I continuously update, optimize, and correct the algorithm tutorials, some historical content and sites should be discarded because more concise and high-quality resources are now available for your learning.
The algorithm tutorials I have published on other platforms are outdated and no longer updated.
The sites I previously used are no longer maintained, including:
Previous PDFs are also outdated, including: "labuladong's Algorithm Cheat Sheet," "labuladong's Problem Solving Notes," "labuladong's Algorithm Secrets," etc.
LeetCode Problem List
At the request of some readers, I have compiled a list of all the problems explained on this site.
However, please note, I personally think this list is not very useful, and I do not recommend practicing directly from it.
The problems in the list are randomly ordered, making it difficult to learn progressively or focus on specific topics.
I recommend studying according to the site's directory order; tackle the problems mentioned as you come across them in the articles. Once you finish the site's content, you'll have completed all the problems in the list.
The only purpose this list might serve is to prove that I'm not exaggerating; this site indeed guides you through solving over 500 problems. After installing the Chrome Problem Solving Plugin, you can open this list to see all problems marked with my solutions/ideas, indicating that they have been covered on this site.
力扣 | LeetCode |
---|---|
https://leetcode.cn/problem-list/59jEaTgw/ | https://leetcode.com/list/9zwo3ww5/ |
About the Author
I am labuladong, the author of the fucking-algorithm repository. I pioneered the framework thinking approach to problem-solving and have frequently topped GitHub Trending. The repository has garnered 125k stars.
My focus is on creating the best algorithm tutorials that are concise and precise rather than broad and comprehensive. I strive to help readers conquer the tough subject of algorithms in the shortest time possible.
Site Membership is the only paid feature of this site. For the cost of a meal, you can unlock all content and tools on the site and enjoy a smooth, seamless learning experience.
How to Read
For Beginners: Follow the order of the site's directory and proceed steadily.
For Intermediate Readers (over 300 problems solved): The content of Chapter 0 is a must-read, while other chapters can be selected based on your needs.
For Readers Preparing for Interviews with Limited Time (less than 30 days): Focus on problem-oriented training, particularly the chapters marked as 【Intensive Practice】
in the directory. This can help build muscle memory for short-term preparation.
The site mainly features three types of articles:
1️⃣ Basic Data Structure Tutorials (about 10% of the site's content)
Primarily found in the chapter Quick Start: Basic Data Structures
. This section explains the implementation principles of commonly used data structures in algorithms and guides you through coding these structures. It generally does not include algorithm problems.
2️⃣ Detailed Explanations of Classic Algorithm Frameworks with Examples (about 50% of the site's content)
For some classic algorithm frameworks or problems, I provide detailed explanations through entire articles with specific examples to help you understand the principles. Each article typically includes 2-5 examples that you can solve as you read.
3️⃣ Exercise Chapters to Help You Master Algorithm Frameworks (about 40% of the site's content)
Content marked with 【Intensive Practice】
in the directory belongs to the exercise section, usually following the algorithm framework content. Compared to examples, exercises focus on applying and integrating what you've learned. I will use numerous exercises to help you train your framework thinking and build muscle memory, ensuring you thoroughly master the solutions for a category of problems. An intensive practice article generally includes 10-20 exercises.
Practical Features of Our Site
1. Support for Algorithm Visualization Animations
All solution codes on our site and its accompanying plugins are equipped with an algorithm visualization panel, allowing you to intuitively observe the execution process and aid in understanding the algorithm logic. This visualization panel is located below the solution code for each problem.
For example, in the algorithm for Finding the Start of a Cycle in a Linked List, you can repeatedly click on the if (fast == slow) break;
line to see the process of fast and slow pointers meeting. Similarly, clicking multiple times on the while (slow != fast)
line will show how the pointers advance synchronously to meet at the start of the cycle:
The visualization panel also supports sorting algorithm visualization. For instance, here is the code for Insertion Sort. You can click the play button in the upper left corner to speed up the playback and observe the sorting process:
Recursive algorithms receive special enhancement in the visualization panel. For example, with the recursive solution of the Fibonacci sequence, you can continuously click on the if (n < 2)
line to see the growth of the recursion tree:
The visualization panel significantly reduces the complexity of understanding intricate algorithms. For more details, please see Introduction to Visualization Panel.
2. Support for Reading History
In the sidebar, unread articles are marked with
The same markers are used in reference links within articles, helping you identify whether you have studied the linked content.
3. Support for All Major Programming Languages
All solution codes on our site and its associated plugins support Java, C++, Python, Golang, JavaScript, and other popular programming languages to cater to a wide range of readers' needs.
The Java code is written by me, while the code in other languages is translated with the assistance of chatGPT but has been verified and debugged by me to ensure correctness and consistency.
4. Code Image Annotations
In our site and its associated plugins, complex code blocks include a light bulb icon. Hovering over this icon will display an image to aid understanding:
class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast, slow;
fast = slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) break;
}
// the above code is similar to the hasCycle function
if (fast == null || fast.next == null) {
// if fast encounters a null pointer, it means there is no cycle
return null;
}
// reset to the head node
slow = head;
// move the fast and slow pointers forward in sync, the intersection point is the start of the cycle
while (slow != fast) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *fast, *slow;
fast = slow = head;
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
if (fast == slow) break;
}
// the above code is similar to the hasCycle function
if (fast == nullptr || fast->next == nullptr) {
// if fast encounters a null pointer, it means there is no cycle
return nullptr;
}
// reset to the head node
slow = head;
// move the fast and slow pointers forward in sync, the intersection point is the start of the cycle
while (slow != fast) {
fast = fast->next;
slow = slow->next;
}
return slow;
}
};
class Solution:
def detectCycle(self, head: ListNode):
fast, slow = head, head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
break
# the above code is similar to the hasCycle function
if not fast or not fast.next:
# if fast encounters a null pointer, it means there is no cycle
return None
# reset the pointer to the head node
slow = head
# both fast and slow pointers move forward in sync, the intersection point is the start of the cycle
while slow != fast:
fast = fast.next
slow = slow.next
return slow
func detectCycle(head *ListNode) *ListNode {
fast, slow := head, head
for fast != nil && fast.Next != nil {
fast = fast.Next.Next
slow = slow.Next
if fast == slow {
break
}
}
if fast == nil || fast.Next == nil {
return nil
}
slow = head
for slow != fast {
fast = fast.Next
slow = slow.Next
}
return slow
}
var detectCycle = function(head) {
let fast, slow;
fast = slow = head;
while (fast !== null && fast.next !== null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) break;
}
// the above code is similar to the hasCycle function
if (fast === null || fast.next === null) {
// if fast encounters a null pointer, it means there is no cycle
return null;
}
// reset the pointer to the head node
slow = head;
// move the fast and slow pointers forward in sync, the intersection point is the start of the cycle
while (slow !== fast) {
fast = fast.next;
slow = slow.next;
}
return slow;
};
Complementary Problem-Solving Plugin
To cater to the diverse needs of readers, I have developed and maintained a complementary problem-solving plugin for this site, allowing users to practice coding in their preferred code editors, even during leisure time.
Within the problem-solving plugin, all exercises explained on this site have special enhancements. You can access short insights or detailed solutions, and use all practical features of this site, such as visualization panels and annotated images.
The problem-solving plugin is not mandatory to install, but I recommend the Chrome browser plugin. This is because while reading this site, you may frequently navigate to LeetCode/力扣 for practice, and the Chrome plugin can provide some assistance. You can choose to install the vscode/Jetbrain plugins based on your personal problem-solving needs.
For detailed installation and usage instructions for each plugin, refer to Chrome Plugin, vscode Plugin, and Jetbrain Plugin.