LeetCode, an honest review

Overview

My LeetCode journey started on Nov 5, 2022, as a way to prepare for an algorithms class. As I did more and more problems, it slowly turned into an obsession. I was doing problem after problem from many different categories. For the duration of 2023 and 2024, every single day, I did at least one problem—a Daily problem if I hadn’t already solved it, or a random problem if I had. Usually, that was all I did, but when I was bored, I would do 5, 10 or even 20 problems.

Statistics

At the time of writing:

Metric Value
Total solved 1,500 problems
Streak 737 of 789 days
Rank 3,601 of approximately 5 million users
Easy 350 / 846
Medium 968 / 1,775
Hard 182 / 785
Badges 44

Routine

During the day, when I found the time, I sat down ready to tackle one problem. I would do my best to solve it without looking at hints and solutions. The goal was to find the best possible algorithm, which in practice meant beating 85% of submissions or more. Depending on the problem, this would take anywhere between 5 and 20 minutes, and then I would try to use a hint in case there was something I’d missed.

If that didn’t help, I would turn to the official or community solution in order to understand what I’d missed and exactly how the algorithm needed to work. Then I would try to implement it myself, often more clearly and concisely. Even if I managed to solve a problem with satisfactory complexity, I would still take a look at the solutions just to see whether there was something worth remembering. I picked up a lot of great tricks this way.

Learning

Because of my competitive programming background from middle school and high school, I was already quite familiar with the format as well as logical thinking, which gave me a head start.

At that time, I had been writing a lot of C, but I wanted to get good at C++. I’d seen the STL before, but I lacked a deep understanding of it. I started with some introductory problems that mostly tested logic, but soon enough I started dabbling with more advanced topics like trees and graphs. That is where the real fun began. I was aware of a few algorithms from the class, but when it came time to actually implement them, I was thunderstruck. It was a crucial step at the time to take a look at other people’s solutions and see exactly how the data structures were represented in C++ code and how to interact with them.

As my knowledge of algorithms grew, so did my understanding of C++, although I spent additional time learning about its inner workings. It came to the point where the language was not an issue anymore. That’s when I started thinking beyond the problem at hand and more about the coding style, as well as the best utilization of the processor and memory.

Problems

There are many different kinds of problems, regardless of their difficulty:

  • Brain teasers—usually math-related and requiring logical thinking
  • Strictly mathematical problems—based on advanced mathematical knowledge
  • Little problems—not necessarily hard, but tricky to implement elegantly
  • Straightforward problems—once you’ve seen the underlying idea, they are not that difficult
  • Problems that require a well-known algorithm in order to be solved. I don’t think any mortal can come up with them in any reasonable amount of time.

Most problems require a specific technique to be solved, such as a sliding window, two pointers, or binary search. The more problems you do, the easier it will be to spot these patterns quickly and implement an adequate solution. An issue may arise when a few of these techniques are required simultaneously.

Difficulty

Easy problems are easy mainly because of the restrictions. Any valid solution, regardless of the complexity, will work. Most of them are trivial, but there are a few hidden gems that serve as an introduction to well-known algorithms to be used in harder problems. This is a good reason to look at other solutions even if the running time is satisfactory—inefficiency is masked by small constants.

Medium problems vary drastically. There are some trivial ones, some that are just tedious to code, some that require a solid understanding of common algorithms and data structures, while some require a specific algorithm that is worth remembering. Due to the wide array of possibilities, there are some medium problems that I’ve solved in under a minute, while even after I’ve done so many of them, from time to time, I come across one where I have no idea how to even start. This is a fact of life, and there is no point in beating your head over it.

Hard problems are weird. There are some that require ultra-specific algorithms, some that require outstanding out-of-the-box thinking while still being possible to come up with. My favorite ones are those that require a perfect understanding of the common algorithms and data structures, then add some twist to them, whether it’s a combination or transformation that is needed in order for them to work. Some are just impossible to understand, even with a solution…

Advice

Doing 1,500 problems is really unnecessary if your main focus is interviews. Focusing on NeetCode will be enough for most people.

There are a few things worth remembering:

  • Code, Code, Code! Every single solution needs to be actually coded, tested and run. There are no problems that are too easy. Everything counts.
  • You need to be aware of your weaknesses, whether it’s your understanding of the language that is holding you back, or some algorithm or data structure.
  • Once you’ve learned a new concept, you should drill it until it becomes second nature. There should be no rush between problems unless everything is crystal clear. Otherwise, you will waste a lot of time reviewing concepts that should have been mastered a long time ago.
  • Not everything is in the algorithms and data structures. Clean and concise code also matters a lot.
  • Copying the solution onto paper by hand really helps internalize the ideas. Do this only for a small number of special problems so as not to waste too much time.

Conclusion

I’ll be taking a break, possibly forever, from LeetCode. It’s been fun, but I’ve passed the point of diminishing returns for where I want to be, so it’s better for me to focus my energy elsewhere. The lessons I’ve learned will continue to serve me in the future, both the algorithms and data structures, as well as the logic and general practice of coding.

I haven’t given competitions an honest shot, mostly due to the inconvenient times at which they are held. They might, however, be a new step forward to keep me from getting rusty.