Introduction
Purpose of This Site
This site helps you develop a structured and template-based approach to solving algorithm problems. On a scale of 100, regardless of your current level, this site can help you reach a score of 85 in the shortest time possible.
Because we teach a template-based and structured thinking approach, the 85 score you achieve will be consistent and reproducible, not reliant on luck. In other words, you will certainly be able to solve problems with a difficulty level below 85, and for problems above 85, inspiration and luck will come into play.
What does a score of 85 mean?
To give you an idea of what a score of 85 represents, imagine you are a computer science major in college who has taken required courses in data structures and algorithms. If you primarily use various development frameworks at work and have never practiced algorithm problems, your level is likely around 30-40.
So, don't think a score of 85 is low; this level is more than sufficient for technical job interviews and written tests. Also, don't fear algorithms—if you use the right methods and dedicate some time to practicing problems, improving your algorithm skills is quite achievable.
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 is recommended to open it directly in WeChat for convenient one-click login.
This site uses a framework-based approach to guide you through solving over 500 LeetCode problems, and the algorithmic thinking you develop will not degrade. Even years later, you will be able to quickly regain problem-solving skills.
By clicking the magnifying glass icon at the top right of the site, you can search its content. It supports direct search by LeetCode problem names, numbers, or links.
The site is continuously being updated and optimized. There are entries for "Update Log" and "Bug Feedback" at the top.
Expired URLs/PDFs/Content
As I continually update, optimize, and correct the algorithm tutorials, some historic content and websites should be discarded because more concise and high-quality content is now available for your learning.
All algorithm tutorials I published on other platforms are outdated and no longer updated.
The website addresses I used previously are no longer maintained, including:
Previous PDFs are also outdated, including: "Labuladong's Algorithm Cheat Sheet," "Labuladong's Problem-Solving Notes," and "Labuladong's Algorithm Secrets."
LeetCode Problem Lists
At the request of some readers, I have compiled a problem list that summarizes all the problems explained on this site.
However, please note that I personally believe that this problem list is not very useful, and I do not recommend you to use it directly for problem-solving.
The problems in the list are randomly sorted, making it impossible to learn progressively or focus on specific knowledge points. I recommend following the site's directory order for learning, and solving the problems mentioned in the articles as you go. By the time you finish this site, you will be able to solve all the problems in the list.
The only purpose of this problem list might be to prove that I am not exaggerating; this site can indeed guide you through solving over 500 problems. After installing the Chrome Problem-Solving Plugin, you can open this problem list and see that all problems have my solutions/thought process marked, indicating that these problems are all explained on this site.
LeetCode CN | 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. Readers usually call me "Dong Ge." 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 This Site
1. Supports Algorithm Visualization Animations
All solution codes on this site and its accompanying plugins are equipped with an algorithm visualization panel. You can intuitively see the execution process of the algorithm, which helps in understanding the algorithm's logic. The visualization panel is placed below the solution code for each problem.
For example, in the algorithm to find the starting point of a cycle in a singly linked list, you can click on the code if (fast == slow) break;
to see the process of the fast and slow pointers meeting:
The visualization panel has special enhancements for visualizing recursive algorithms. For example, in the recursive solution for the Fibonacci sequence, you can keep clicking on the line if (n < 2)
to see the growth of the recursion tree:
The visualization panel can greatly reduce the cost of understanding complex algorithms. For more details, please refer to Introduction to the Visualization Panel. We won't delve into it too much here.
2. Supports Reading History
In the sidebar, articles you have completed will be marked with a
Referenced links within articles will also have the same markers, so you can easily know whether you have already studied a particular article.
3. Supports All Major Programming Languages
All solution codes on this site and its accompanying plugins support Java, C++, Python, Golang, JavaScript, and other commonly used programming languages. This ensures that the needs of a broad audience are met.
The Java code is written by me, while the code for other languages has been translated with the help of ChatGPT. However, I have personally verified and debugged all translated code to ensure accuracy and consistency.
4. Code Image Annotations
On this site and its accompanying plugins, for more complex code blocks, there will be a small lightbulb 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;
};
Our Site's Complementary Problem-Solving Plugins
To cater to the diverse needs of different readers, I have developed and maintained complementary problem-solving plugins for our site. These plugins support many practical functions, allowing readers to solve problems in their preferred code editors, making it more convenient.
All the problems discussed in our tutorials and exercises have special enhancements in the problem-solving plugins, allowing readers to directly view my solutions or jump to the corresponding article on our site.
Installing these plugins is not mandatory, but I recommend installing the Chrome browser plugin since you might frequently jump to LeetCode pages while reading our site. The Chrome plugin can provide you with some assistance. You can choose to install the VSCode or Jetbrains plugin based on your problem-solving needs.
For detailed installation and usage instructions for each problem-solving plugin, see Chrome Plugin, VSCode Plugin, and Jetbrains Plugin.