Introduction
If 100 is the full score, no matter your starting level, this site can help you reach an 85 within the shortest time.
This is because we teach you how to think with templates and frameworks. So once you master this, your 85 score is solid and stable, not lucky. That means, for problems below 85 difficulty, you can solve them step by step. For those harder than 85, then luck and inspiration matter.
What does an 85 mean?
For example, suppose you majored in computer science in college, took the required data structures and algorithms courses, use development frameworks at work, but never practiced algorithm problems. Then your skill is about 30-40 points. Really, algorithm is an independent ability. It is not the same as programming experience. You need to practice specifically to improve.
So, do not feel 85 is low. This level is already enough for tech job interviews and normal contests. Also, do not be afraid of algorithms. If you use the right method and spend time practicing, it is easy to improve.
Website Structure
Introduction
Tools and Algorithm Visualization
Algorithm Visualization Introduction Algorithm Game Introduction Chrome Extension for LeetCode vscode Plugin for LeetCode JetBrains Plugin for LeetCode Subscribe to this Algo Notes
Study Plans for Beginners and Quick Mastery
Learning Plan for Quick Mastery Learning Plan for Beginners How to Learn Algorithms Efficiently How to Practice
Programming Language Basics
Chapter Introduction C++ Basics Java Basics Golang Basics Python Basics JavaScript Basics LeetCode Guide Let's Have Fun with LeetCode
Getting Started: Data Structures and Sorting
Implement Dynamic Arrays
Implement Single/Double Linked List
Array and LinkedList Variations
Implement Queue and Stack
Implement HashMap
Hash Table Variations
Binary Tree Structure and Traversal
Binary Tree Variations
Graph Structure and Algorithm Overview
Implement and Visualize 10 Sorting Algorithms
Chapter Introduction 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 Thinking Recursion Algorithms from Binary Tree Perspective One Perspective + Two Thinking Patterns to Master Recursion Dynamic Programming Common Patterns and Code Template Backtracking Algorithm Common Patterns and Code Template BFS Algorithm Common Patterns and Code Template Backtracking Algorithm to Solve All Permutation/Combination/Subset Problems Greedy Algorithms Principles and Techniques Divide and Conquer Principles and Techniques Time and Space Complexity Analysis Practical Guide
Chapter 1. Data Structure Algorithms
Linked List Algorithm
Array Algorithm
Two Pointer Techniques for Array Problems Match Three Game Tricks to Traverse a 2D Array Exercise: Two Pointer Techniques for Array Game of Life One Trick to Solve All N-Sum Problems 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
Stack/Queue Algorithm
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
Binary Tree Algorithm
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)
Master 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
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 Basic Segment Tree Implementation Dynamic Segment Tree Implementation Lazy Update Segment Tree Implementation Exercise: Segment Tree Problems Implementing Trie 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 Algorithm
How to Determine a Bipartite Graph Hierholzer Algorithm to Find Eulerian Path Exercise: Eulerian Path Cycle Detection and Topological Sort Algorithm Union-Find Algorithm Exercise: Union-Find Problems on LeetCode Dijkstra Principles and Implementation Dijkstra Algorithm with Restrictions Exercise: Dijkstra Problems Kruskal Minimum Spanning Tree Algorithm Prim Minimum Spanning Tree Algorithm
Chapter 2. Brute Force Search
DFS and Backtracking Algorithm
Backtracking Algorithm Common Patterns and Code Template Backtracking in Action: Sudoku and N-Queens Implement Sudoku Cheat Backtracking Algorithm to Solve All Permutation/Combination/Subset Problems Some Questions About Backtracking and DFS Algorithms Solve All Island Problems with DFS Minesweeper Game II Ball and Box: Two Perspectives of Backtracking Enumeration 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 Multi-source shortest path: Floyd algorithm 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
Dynamic Programming ProblemSet
Greedy
Chapter 4. Other Common Techniques
Mathematical Techniques
LeetCode Problems with One Line Solution Common Bit Manipulation Techniques Minesweeper Game I 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 Exercise: 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 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
Computer Basics
Design Pattern
How to Read
If you have little time to prepare (less than 30 days), you can follow the Quick Mastery Study Plan.
If you already have some experience (solved more than 300 problems), chapter 0 is a must-read, others you can choose as needed.
If you are a beginner, read in the site directory order and make steady progress.
The site works well on PC and mobile. You can finish all algorithm interview preparation in one place:

What Is On This Site
Our content includes text tutorials and video explanations, divided into three parts:
1️⃣ Data Structure Tutorials (about 10%)
Mainly in Data Structures and Sorting. This chapter teaches sorting and explains key ideas and code for classic data structures. There are usually no algorithm problems here. The goal is to help you know the data structures used in work and the special ones used in problem solving, so you can apply them directly later.
2️⃣ Explaining Classic Algorithm Frameworks with Examples (about 50%)
For classic algorithm frameworks or problems, I use whole articles with concrete examples to explain them in detail. The goal is to help you understand the ideas. Usually there are 2-5 examples per article, which you can solve as you read.
3️⃣ Practice Problems to Help You Master the Frameworks (about 40%)
Sections marked with Exercise
are practice parts. They come right after the algorithm frameworks. All practice problems follow the framework directly, letting you build muscle memory and fully master a type of solution. Each practice set has 5-10 questions you can solve quickly after learning the framework.
This site helps you solve hundreds of LeetCode free problems. Most are for practicing algorithm frameworks. Once you master the frameworks, you can solve most of them in minutes, often almost automatically.
LeetCode Problem Lists
By request, I made problem lists summarizing all the problems on this site. After installing the Chrome extension, you can click the lists below and see my solutions marked.
But, I think these lists are not very useful and do not suggest practicing directly from them. The order is random, so you cannot learn step-by-step or focus on one topic. You also do not need to finish all these problems; after you learn the main frameworks, you can solve most problems quickly, no need to grind all of them.
LeetCode China | LeetCode Global |
---|---|
https://leetcode.cn/problem-list/59jEaTgw/ | https://leetcode.com/list/9zwo3ww5/ |
I suggest studying with the Beginner Study Plan or Quick Mastery Study Plan. They have grouped problem lists. The VS Code extension and Jetbrains extension also work with these plans for easy use.

Deprecated Links/PDFs/Content
This is the latest website: labuladong.online.
I am always updating and improving the content. Old sites or content are now outdated, and you should learn from this new, better site.
Other platforms where I posted algorithm tutorials are outdated and no longer updated.
The following old URLs are no longer maintained:
Old PDFs are outdated too, such as: "labuladong’s Algorithm Cheat Sheet", "labuladong’s Problem Notes", "labuladong’s Algorithm Manual", etc.
I really care about your learning experience, so I keep updating and making the content better. There are links at the top for the update log and bug feedback.
About the Author
I am labuladong, author of the fucking-algorithm repo. Readers call me "dong ge". I am the first to use "framework thinking" to solve algorithm problems. My repo was many times on GitHub Trending, and now has 125k stars.
My style is to focus on quality, not quantity. This site targets only algorithm practice. It is direct and precise, helping you master algorithms fast.
Site subscription is the only paid offering. With the price of a meal, you unlock all content and tools, enjoying the smoothest learning experience.
Useful Features of This Site
Quick Learning Roadmap
We provide an Algorithm Quick Mastery Plan with a clear learning roadmap. Click each node to see related articles and problem lists. This helps you easily track your learning progress.
Algorithm Quick Mastery Roadmap
Algorithm Visualization
Every solution on this site and all our plugins comes with an algorithm visualization panel under the code. You can see how the algorithm works step by step, which helps you understand the logic better.
For example, in this algorithm for finding the start of a cycle in a linked list, you can click the line if (fast == slow) break
several times to see how the fast and slow pointers meet. Keep clicking while (slow != fast)
to watch them move together and find the start of the cycle.
Example 1: Color System and Interaction
The visualization panel works well with complex data structures and recursion. Here is a DFS algorithm on graphs to find all paths from node 0
to node 4
. Click if (s === n - 1)
several times to see how the graph traversal and recursion work.
Example 2: Complex Structures and Recursion
The visualization panel can show data structures in different ways to help readers understand them.
For example, it uses a bar chart to show the array during insertion sort. You can click the play button at the top left to speed up and watch the sorting process.
Example 3: Sorting Algorithms
The visualization panel helps you understand complex algorithms much easier and supports all data structures and algorithms. Here we only show a few examples. You can see more classic algorithm visualizations on the Quick Visualization Reference Page.
Learn by Playing Games
Visualization helps you see how algorithms work. However, just practicing problems may feel boring. I want to connect algorithms with real life, so you can truly enjoy learning algorithms.
One idea is to combine algorithms with games. We usually use our hands to play games, but can we use algorithms to control the game?
So, I designed some classic mini games where I separate the algorithm module. You are given a game scene and asked to write code to control the game engine, so you can finish the game or complete a task that is hard to do manually.
This gives you a strong sense of achievement and helps you see how algorithms are used in real scenarios.
For example, here's a snake game. Try writing the logic to move the snake and eat food. It may seem hard at first, but it's actually easy if you use basic linked list operations:
For more fun mini games, see Algorithm Games List and Introduction.
Support for All Popular Programming Languages
All solution code on this site and all plugins support Java, C++, Python, Golang, JavaScript, and other common languages. This helps more readers with different language needs.
All code has been tested and debugged by me to make sure it is correct and consistent.
The site and all plugins also support code image annotations. For complex code, you will see a light bulb icon. Hover your mouse on it to see an image to help understand the code.
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) {
// fast encountering a null pointer means there is no cycle
return null;
}
// reassign to the head node
slow = head;
// move fast and slow pointers at the same pace, the
// intersection point is the cycle's entry point
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
}
}
// 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 cycle
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;
};
Other Useful Features
Supports reading history. In the sidebar and all articles, articles you have not read are marked with
Supports focus mode. On desktop, there's a "Focus Mode" switch at the top right. When turned on, it will blur the sidebar and top bar. This helps you focus, or makes it easier to learn when you're at work.
Supports site-wide search. The search box at the top right can search the whole site. You can enter LeetCode problems, problem numbers, or links to find explanations directly.
Practice Plugin to Help Learning
To meet the needs of different readers, I have developed plugins for practicing problems, so you can practice in your favorite code editors. It's also good for sneaky practice at work.
The plugin includes the Beginner's Catalog and Quick Mastery Catalog, supports local code debugging, and lets you view solution explanations, visualization panels, and code image annotations easily.
The practice plugin is not required, but I suggest installing the Chrome plugin. When reading this site, you may jump to LeetCode pages to practice. The Chrome plugin gives you extra help. You can also install vscode or Jetbrain plugins as needed.
For installation details of each practice plugin, see Chrome Plugin, vscode Plugin, and Jetbrain Plugin.