Introduction
Utility of This Site
This site helps you develop a structured and templated approach to solving algorithm problems. Regardless of your starting point, you can improve your skills to an 85 out of 100 score in the shortest possible time.
Since the site teaches a templated, structured thinking pattern, achieving this score of 85 is consistent and not reliant on luck. In other words, you will definitely solve problems with a difficulty level below 85, while those above 85 may require some inspiration and luck.
What Does a Score of 85 Mean?
For comparison, if you majored in computer science in college, attended mandatory courses on data structures and algorithms, and primarily used various development frameworks in your work without practicing algorithm problems, your skill level would likely be around 30 to 40. This is because algorithms can be considered a separate skill set from programming experience, requiring dedicated practice.
So, don't think of an 85 as low; this level is more than sufficient for technical job interviews and exams. Moreover, there's no need to fear algorithms. With the correct approach and dedicated practice, improving your algorithm skills is quite achievable.
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
Study Plans for Beginners and Quick Mastery
How to Learn Algorithms Efficiently Learning Plan for Beginners Learning Plan for Quick Mastery How to Practice Algo Visualization Cheat Sheet
Getting Started: Programming Language Basics
Chapter Introduction C++ Basics Java Basics Golang Basics Python Basics JS Basic to Use the Algo Visualization LeetCode Guide Let's Have Fun with LeetCode
Basics: Data Structures and Sorting
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
Chapter Introduction 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
Cycle Detection and Topological Sort Algorithm Searching for a Celebrity How to Determine a Bipartite Graph Union-Find Algorithm Exercise: Union-Find Problems on LeetCode Kruskal Minimum Spanning Tree Algorithm Prim Minimum Spanning Tree Algorithm Dijkstra Algorithm Template and Applications Exercise: Dijkstra Problems
Chapter 2. Brute Force Search
DFS and Backtracking Algorithm
Backtracking Algorithm Common Patterns and Code Template Backtracking in Action: Sudoku and N-Queens 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: 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
Reading Guide
For readers with limited time (preparation time < 30 days), you may follow the sequence in the Quick Learning Plan.
For readers with some foundation (completed over 300 problems), Chapter Zero is a must-read, while other chapters can be chosen based on your needs.
For beginners, follow the sequence of the site’s directory for a solid understanding. The site is compatible with both PC and mobile devices:
Content of the Site
The site mainly consists of three types of articles:
1️⃣ Basic Tutorials on Data Structures (comprising about 10% of the site's content)
This is mainly concentrated in the chapter on Detailed Explanation of Data Structures and Sorting
. This section explains the core principles and code implementations of sorting algorithms and classic data structures. It generally does not include algorithm problems. The primary aim is to help readers understand the principles of data structures commonly used in work and those unique to algorithm problems, allowing you to apply them directly in the future.
2️⃣ Detailed Explanation of Classic Algorithm Frameworks with Examples (comprising about 50% of the site's content)
For some classic algorithm frameworks or problems, I provide comprehensive articles combining specific examples for detailed explanations, aiming to help you understand the principles. Typically, each article contains 2-5 example problems, which you can solve as you read.
3️⃣ Exercise Chapters to Help You Master Algorithm Frameworks (comprising about 40% of the site's content)
Content marked with 【Enhanced Practice】
in the directory belongs to the exercise section, generally following the algorithm framework content. The exercises are problems that can be directly applied to the framework, aiming to help you develop muscle memory through repeated practice and thoroughly grasp the solution of a type of problem. Each enhanced practice contains about 10 exercises, and once you master the algorithm framework, you can solve them quickly.
The site can guide you in solving 500+ freely available problems on LeetCode. Most of these problems are for practicing framework thinking. As long as you master a few core algorithm frameworks, you can solve them in minutes, completing all these problems almost effortlessly.
About This Site
Bookmark the latest address for continuous updates: labuladong.online
This site supports both mobile and PC reading. It is recommended to open the site directly within WeChat on mobile for easy one-click login.
This site can guide you step-by-step through solving over 500 LeetCode problems, and the algorithmic thinking you develop will remain sharp, allowing you to quickly regain problem-solving skills even years later.
Click the magnifying glass icon in the upper right corner of the site to search its contents. You can search for LeetCode problems by title, number, and link in both English and Chinese.
The site is continuously updated and optimized. There are links for "Update Log" and "Bug Feedback" at the top.
Expired URLs/PDFs/Content
As I constantly update and improve the algorithm tutorials, some historical content and websites have been deprecated, as more concise and high-quality content is now available for your learning.
Algorithm tutorials I published on other platforms are outdated and no longer updated.
The website addresses I previously used are no longer maintained, including:
Older PDFs are also outdated, including: "Labuladong's Algorithm Cheatsheet," "Labuladong's Problem-Solving Notes," "Labuladong's Algorithm Secrets," and others.
LeetCode Problem List
Upon request from some readers, I have compiled a problem list that summarizes all the problems discussed on this site.
However, please note, I personally find this problem list not very useful and do not recommend using it to directly practice problems.
The problems in the list are randomly ordered, making it difficult to learn progressively or focus on specific topics. Moreover, it's unnecessary to complete all these problems.
I suggest following the order of the site’s directory for learning. Just practice the example problems mentioned in the articles as you go. Most problems in the list are framework exercises, designed to train your framework thinking. Once you grasp the core algorithm frameworks, you can solve them quickly without deliberate practice.
The sole purpose of this list might be to prove that I’m not exaggerating. This site can indeed guide you through solving over 500 problems using algorithm frameworks. After installing the Chrome Plugin, you can open this list to see that each problem has my solutions or ideas marked, indicating these problems are covered by the tutorials on this site.
LeetCode CN | LeetCode |
---|---|
https://leetcode.cn/problem-list/59jEaTgw/ | https://leetcode.com/list/9zwo3ww5/ |
Based on reader feedback, I want to emphasize a common misconception: The problem list is not the focus; the systematic knowledge framework is the key.
Even if you have past exam questions, without a framework mindset for various algorithms, you will just end up memorizing problems, which is not useful.
If a problem changes slightly, you might struggle, because mastering common algorithm frameworks is the basis for applying knowledge in new situations.
Therefore, my suggestion is to first understand common algorithm frameworks, and then consider whether to look at past exam problems. By then, any problem list will not make much difference, and you can go through it in a couple of hours.
The focus of this site has always been on teaching core algorithm frameworks. The main purpose of exercises is to help you internalize these frameworks, ensuring that when you encounter similar new problems in the future, you can solve them independently.
About the Author
I am labuladong, the author of the fucking-algorithm repository. Readers often call me "Dong Ge." I pioneered the framework-thinking approach to problem-solving and have frequently topped the GitHub Trending list, currently earning 125k stars.
My goal is to create the best algorithm tutorial, focusing on being concise and precise rather than comprehensive; striving to help readers master algorithms, a notoriously difficult subject, in the shortest time possible.
This site's subscription is the only paid service offered, and for the cost of a meal, you can unlock all content and tools on the site, ensuring a smooth and seamless learning experience.
Useful Features of the Website
1. Support for Algorithm Visualization Animations
On this website and all associated plugins, every solution code is accompanied by an algorithm visualization panel, allowing you to intuitively observe the execution process of the algorithm and aiding in understanding its logic.
The visualization panel significantly reduces the complexity of understanding algorithms, supporting all data structures and algorithms. These are just a few examples. More classic algorithm visualizations can be found on the Algorithm Visualization Quick Reference Page.
2. Support for Reading History
In the sidebar and within all articles, links to unread articles are marked with
Reading data is automatically synchronized across all devices.
3. Support for All Major Programming Languages
This website and all associated plugins support solution codes in all common programming languages such as Java, C++, Python, Golang, and JavaScript, catering to the needs of a broad audience.
Java code is written by me, while codes in other languages are translated with the assistance of chatGPT but have been personally verified and debugged by me to ensure accuracy and consistency.
4. Code Image Annotations
This website and all associated plugins feature a light bulb icon next to more complex code blocks. Hovering over the icon will display images 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
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
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
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
}
}
// the above code is similar to the hasCycle function
if fast == nil || fast.Next == nil {
// if fast encounters a null pointer, it means there is no cycle
return nil
}
// 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
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
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.