Red-Green-Code

Deliberate practice techniques for software developers

  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter

LeetCode Tip 10: Planning a Spaced Repetition Schedule

By Duncan Smith Leave a Comment Mar 15 0

LeetCode 2023

For most programmers, solving coding interview problems is not a natural way of coding. It takes time and practice to get good at them. Using spaced repetition techniques makes this practice time more effective.

The canonical example of spaced repetition is using flashcards to learn language vocabulary. Anki is a popular software application that implements spaced repetition by presenting each flashcard at the optimal time. In vocabulary study, each card is fairly short, just a single word and definition. But there are many cards to learn, since learners need to know thousands of words to become fluent in a language.

For coding interview problems, the quantities and material to learn are quite different. The well-known Blind 75 list, as its name implies, has only 75 model LeetCode problems. Even the largest list on NeetCode has only 327 problems. Each of these problems might require 25-50 lines of code to solve. That’s small by real-world programming standards, but there’s a lot of detail packed into those lines.

Algorithm implementation is a different kind of knowledge than vocabulary definitions. You wouldn’t want to memorize how to implement binary search the way you learn what a word means. Given these differences, you might wonder how applicable spaced repetition is to LeetCode problems. Maybe it’s better to solve a problem once, write a detailed model solution to make sure you understand all the details, and then move on to a new problem.

The problem with this approach is that if you only solve a problem once, you’ll never practice recalling the details of the solution from memory, which means you probably won’t remember how to solve it. Although they represent different types of learning, a complex activity like implementing an algorithm and a simpler activity like defining a vocabulary word both use the brain’s long-term memory functions. Rather than having to re-discover the principles of binary search when you need that algorithm, you can instead remember your model solution. That frees up more of your 30-minute interview to adjust your implementation to the specific problem you need it for.

To make this more concrete: If you want to remember how to implement binary search in a year, it’s not enough to practice once today and again after a year. Instead, start out with small intervals and increase them with each repetition. The basic interval is one full day (since sleep is important for consolidating learning). So when you’re learning a new model solution, start by practicing it every day for a few days. Once that becomes easy, a rule of thumb is to double the time interval after each successful practice session: Two days, four days, eight days, and so on. Adjust the interval times based on how hard a repetition is. If you’re using an eight-day interval and the problem seems very easy, try skipping 16 days and go directly to 32. If it’s too hard, stay at the same interval or cut it in half. Once you get to 256 days, you have probably learned the problem for the purpose of interviewing. You can either remove it from your model problem list to make room for another problem, or just practice it once a year to make sure you still know it.

This year, I’m publishing a series of tips for effective LeetCode practice. To read the tips in order, start with A Project for 2023.

LeetCode Tip 9: Spaced Repetition

By Duncan Smith Leave a Comment Mar 8 0

LeetCode 2023

One way to use LeetCode is to solve as many problems as possible. The argument for that approach is that the more problems you solve, the more experience you get, which will make it more likely that you’ll be able to solve the problems you encounter in an interview. There is some merit to this argument. If you never practice solving binary tree problems, it’s unlikely that you’ll be successful if an interviewer asks you to reverse a binary tree. However, the opposite may not be true. If you practice 100 binary tree problems, you might still not solve the particular binary tree problem you encounter in an interview.

The purpose of model problems and model solutions is to improve the quality of your practice, independent of the number of problems you solve. You should add a problem to your list of model problems because you think it’s the best problem you know of to learn a particular skill. The model solution you create for that problem explains everything important about that problem, including parts you may not notice if you just solve it once and move on.

But writing a model solution doesn’t mean you’re done with a problem. It’s good experience to select a model problem, solve it on your own, study other people’s solutions, and write your model solution. You’ll know a lot more about that problem than you did when you started, and you’ll know better how to solve related problems. But even after doing this work, you’ll be far from an expert in that problem. If you doubt this, find a LeetCode Medium problem and follow the preceding steps to write a model solution for it. Then wait 30 days and try to solve it under timed interview conditions. My guess is that you’ll find it challenging, even though you’re re-solving a problem that you have studied in depth.

To effectively use model problems and solutions, you need another tool, spaced repetition. When you first study a LeetCode Medium problem, there are a lot of details to keep track of. You have to understand what the problem is asking, the algorithms and data structures you need to use to compute the result, and the implementation details for your chosen language. It can be difficult to keep everything straight, so you may not have the spare mental capacity to learn the more general lessons the problem offers. But if you repeat the problem a second time, some of it will be familiar. You won’t have to think as much about some parts of the problem-solving process. You’ll be able to focus on details that you may have missed the first time. With each repetition, some aspect of the problem will become easier, until you reach a level of mastery where you can solve the problem from start to finish with minimal effort.

That’s the repetition part. The spaced part is the time between repetitions. If you solve the same LeetCode Medium problem every day, it will get quite easy after a few days. But if you stop practicing it for 30 days and pick it up again, you might discover that it has somehow become difficult again. To avoid this problem, you need to schedule your repetitions effectively. In the next tip, we’ll look at how to design a spaced repetition plan that makes the most of each practice session.

This year, I’m publishing a series of tips for effective LeetCode practice. To read the tips in order, start with A Project for 2023.

LeetCode Tip 8: Anatomy of a Model Solution

By Duncan Smith Leave a Comment Mar 1 0

LeetCode 2023

Writing your own model solution for a LeetCode problem can help you clarify the solution details in your mind, and it leaves you with a living document to use and improve each time you practice the problem. As an example of what to include in a model solution, I’ll use the one I wrote for LeetCode 1818: Minimum Absolute Sum Difference.

Here are the sections I recommend including in a model solution:

Problem

Rewrite the problem statement in a way that makes sense to you. LeetCode problem statements aren’t always written in the most understandable way, and even if a problem statement is clear to some readers, it may not be clear to you. So write your own. This section is also a good place to introduce variables you can refer to in the solution.

Solution

Now that you clearly understand the problem, write the solution itself.

Intuition

Summarize the key challenges posed by the problem, and the main approach you will use to solve it. When you’re writing the more detailed sections below, make sure they follow the general plan explained in this section. If they don’t, either adjust the details or adjust the plan. You can also use the intuition section to remind yourself how to solve the problem if you forget what approach you used in a future practice session. In this way, it’s a bit like the hints that LeetCode provides for some problems. But while LeetCode authors write hints cryptically, so they don’t give away too much, you should write your intuition section clearly.

Algorithm ideas

In LeetCode discussion posts, authors often jump to the solution without explaining how they figured it out. The algorithm ideas section is for explaining how you got from the intuition to the final product, including any false starts that can help explain why you solved the problem in the way you did.

Algorithm

LeetCode problems focus on algorithms and data structures. The algorithm section explains the final algorithm that you used to solve the problem. Usually, you’ll want to explain the algorithm using pseudocode. There is no official pseudocode syntax like there is for a programming language, so use whatever form of pseudocode is most understandable to you. For the Minimum Absolute Sum Difference solution, I used a bulleted list, with the statements inside the for loop indented as they would be in code. For a more code-like pseudocode format, see my model solution for LeetCode 227: Basic Calculator II.

Algorithm Notes

For some problems, it may not be clear why the algorithm works, even when the explanation is well written. Example cases or test data can help clarify how the algorithm handles different input. For an example of explaining why an algorithm works by enumerating all cases, see my model solution for LeetCode 1288: Remove Covered Intervals. This model solution also uses diagrams, which make most model solutions more understandable.

Code

Finally, we have the actual code, meaning code that LeetCode would accept if you submitted it. If you used code ideas from other sources, this is a good place to link to those in case you want to look them up later. Although LeetCode doesn’t care about code comments, it’s useful to add them to your model code to show where you implement each step of the solution. If there are any remaining questions about what each code block does and why it works, this is the place to clear them up.

This year, I’m publishing a series of tips for effective LeetCode practice. To read the tips in order, start with A Project for 2023.

LeetCode Tip 7: How to Write a Model Solution

By Duncan Smith Leave a Comment Feb 22 0

LeetCode 2023

Practicing a LeetCode problem with the help of a model solution ensures that you are learning an optimal solution, not just any accepted solution. But don’t just take someone else’s solution as your model solution. Use what others have written, and make it your own.

Once you choose to include a problem in your set of model problems, you can begin writing the model solution. After you solve the problem once, the next step is to do some research. Review what others have written about the problem to see what approaches are available. Most problems are amenable to a few different approaches, but model solutions should focus on just one of them. For an especially good model problem, you could write two separate model solutions using two different approaches. But I would recommend finding a second model problem for practicing the second approach. LeetCode has plenty of problems, and it’s rare to find a single problem that is truly the best choice for learning two different solution patterns.

The solution approach will dictate which algorithms and data structures to use for your solution. Collect a few example solutions that use a similar approach. This will show you how different people implement the same type of solution. You may find that one of these examples meets your needs, but you can often combine the best parts of multiple solutions.

Next, make sure you understand how the solution works, and why each block of code is necessary. Go through your example solutions and draw diagrams, write explanations, and add code comments. These artifacts will be useful for any problem, but depending on the problem type, some of them will be more useful than others. For example, a geometry problem lends itself to pictures, while equations may work better to explain a number theory problem. I find it useful to write up a formal solution (an editorial in competitive programming jargon) like this one I wrote for LeetCode 1818: Minimum Absolute Sum Difference. I think it helps present the solution research in an organized way that helps me remember how it all works when I come back to it later.

Of course, you’ll also need to write your own code for your model solution. It will have some relationship to the example solutions that you found during the research phase, but you’ll write it in your preferred language, using your own unique coding style. And most importantly, you will get the experience of writing a solution from scratch.

Your model solution isn’t done when you have working code and an editorial explaining why your code works. You should practice model solutions repeatedly. Each time you practice, you might notice some code that you can make clearer, or a section of the editorial that isn’t as understandable as it could be. When this happens, update your model solution. A source control system like Git comes in handy here, so you can review your changes and revert if something doesn’t work as expected. Updating your model solution regularly ensures that it captures what you learn each time you practice it, and that older solutions take advantage of lessons from newer ones.

This year, I’m publishing a series of tips for effective LeetCode practice. To read the tips in order, start with A Project for 2023

LeetCode Tip 6: Model Solutions

By Duncan Smith Leave a Comment Feb 15 0

LeetCode 2023

A well-chosen model problem gives you a vehicle for studying a specific concept. When you first select a problem, it’s good practice to see if you can solve it on your own using what you already know about the concept. But a problem is useful for practice even after you have solved it once. A problem that you have already solved is best used along with a model solution.

Selecting a problem you haven’t seen before and solving it for the first time is a good way to simulate what happens in a coding interview. But it’s only one type of practice, and you shouldn’t spend all your time practicing that way. Instead, reserve some of your practice time for problems you have already solved. This is where you need a model solution, which you can think of as the best solution you can create using all the resources available to you.

Once you submit your own solution, compare it with examples like the official LeetCode solution, the solutions posted by others in the LeetCode discussions, and solutions found elsewhere on the Web. This process, known as upsolving in competitive programming circles, is a key part of practicing a problem. Even if the LeetCode online judge accepted your first solution, there are other ideas that you could use to improve your solution, or to make your solution more useful in solving other problems.

The model solution emerges from this research. As you study other solutions, you can rewrite or update your model solution using the best ideas you find. Use your own coding style and make sure you understand each step. Think about whether the solution prioritizes runtime or memory usage, and whether you can write a different version that makes the opposite trade-off. At the end of this process, you’ll have one or two high-quality solutions to your model problem, and a foundation for building solutions to other problems that are based on the same concept.

This year, I’m publishing a series of tips for effective LeetCode practice. To read the tips in order, start with A Project for 2023

LeetCode Tip 5: Choosing a Model Problem

By Duncan Smith Leave a Comment Feb 8 0

LeetCode 2023

In the model problem approach to LeetCode practice, the goal is to focus on specific problems rather than abstract concepts. For example, instead of focusing on the general properties of hash tables, or even hash table syntax in a particular language, find a problem that uses hash tables and study that problem. You’ll still learn the concepts, but you’ll have an implementation to associate them with. Then when you need hash tables to solve a new problem, you can retrieve your model problem implementation (either from memory or from your source code repository) and map it to the new problem.

To use the model problem approach, we need to choose model problems. Some problems make better model problems than others. Here are some principles to consider as you make your choice:

  • Pick the right problem for your level: To improve at a skill, it’s best to practice problems that are slightly above your comfort level. For a model problem, the requirements are a bit different. Your aim in solving a model problem is to create an implementation that you can use in the future. Much of the skill improvement comes later, when you use your model problem to understand harder problems. For that reason, it’s fine if the model problem is easier than problems you would normally select for practice.

  • Switch model problems over time: It’s hard to find a single model problem that covers every detail of a programming concept. So once you’re familiar enough with a model problem that you can confidently implement it, find another one that approaches the concept from a different angle. After you do this a few times, you’ll have a set of model problems that provide broad coverage of the concept.

  • Choose a problem that focuses on the concept: If a problem uses a hash table as its primary data structure, but the hard part of the problem is in some other area, it’s not the best choice for a hash table model problem. One rule of thumb: The easier a problem is (in LeetCode’s Easy – Medium – Hard difficulty system) the more it’s likely to focus on fundamental concepts, and the less creative thinking is required. It’s good to practice creative thinking once you’re familiar with a concept, but learn the concept first.

  • Check the like/dislike ratio: Each LeetCode problem shows how many users have liked or disliked it. This is one way to filter out problems that rely on tedious implementation details rather than fundamental concepts. You may get tedious implementation problems in interviews, so you have to practice them, but they’re not the best choice for model problems.

This year, I’m publishing a series of tips for effective LeetCode practice. To read the tips in order, start with A Project for 2023

LeetCode Tip 4: Model Problems

By Duncan Smith Leave a Comment Feb 1 0

LeetCode 2023

The first goal of LeetCode practice is to learn how to solve problems associated with one concept. A LeetCode tag identifies each concept, and each problem has one or more tags. In the beginning, you don’t have to worry about learning concepts more granular than a tag, determining what concept an unknown problem is looking for, or solving a problem within a time limit. Those are all worthwhile skills to learn, but they are better left for later.

Although focusing on one tag is a narrow goal, let’s narrow it down a bit more. The hash table tag currently has 449 problems. To get started, we could solve the first easy problem, read a textbook chapter about hash tables, or check if one of LeetCode’s Explore cards covers hash tables. Instead, I suggest approaching the goal by starting with a model problem.

Serious study of algorithms and data structures often begins when you take a course, and such courses rely on practice problems. (Programming is a skill that you can’t learn just by reading about it). The model problem approach combines problem-based learning with the strengths of the LeetCode platform. The idea is to pick a concept, then find one or more problems that apply that concept in a way that you find understandable. When you need to apply the concept to a new problem, you can then draw on your experience with the model problems.

For example, let’s say you’re starting one of the 449 hash table problems. One approach would be to think about what you know about hash tables — you can insert and retrieve data in (average) constant time, you can store key/value pairs, each key must be unique — and map them to aspects of the problem. With the model problem approach, you instead think about a specific hash table problem that you have learned well, and you map parts of that problem to the new problem. Rather than concepts or pseudocode, you can map blocks of actual code. When you learned the model problem, you practiced correct syntax and typical usage patterns, so you have examples in your head of how hash tables help solve a specific problem. You can apply this practical knowledge to the new problem, rather than having to first translate hash table theory into practice.

This year, I’m publishing a series of tips for effective LeetCode practice. To read the tips in order, start with A Project for 2023

LeetCode Tip 3: A Goal for LeetCode Practice

By Duncan Smith Leave a Comment Jan 25 0

LeetCode 2023

If you believe in the goal of preparing for coding interviews and you agree that LeetCode is a good way to pursue that goal, you may feel like getting on the site and building a daily streak. But it’s important to pick the right priority to focus on during this daily practice. While you can get some benefit out of simply opening LeetCode’s daily challenge problem and trying to solve it every day, there’s something missing from this type of practice. This year’s tips will fill in the gaps in the familiar “practice, practice, practice” approach.

Companies don’t use algorithmic coding interviews to test you on every conceivable computer science or software engineering topic. They focus on a relatively small set of concepts. You can find these concepts in the list of tags on the LeetCode problem page. Ordered by how often they appear in the LeetCode problem set, the first 10 concepts are Array, String, Hash Table, Dynamic Programming, Math, Sorting, Greedy, Depth-First Search, Database, and Breadth-First Search.

With this list of concepts in mind, we can target a more specific practice goal. Rather than practicing the skill of “solving LeetCode problems,” we can instead practice the skill of “solving Dynamic Programming problems” or “solving Depth-First Search problems.” That’s not to say that this skill will give you what you need to solve any problem, since you won’t always know which concept you need to use. But if you suspect that you’re looking at a Depth-First Search problem, it won’t do you much good unless you know how to implement Depth-First Search.

With that in mind, our first set of LeetCode tips will look at a process for learning the LeetCode algorithms, data structures, and techniques found in the tag list. We can ignore, for now, the general problem of how to solve a random LeetCode problem. Instead, we’ll focus on choosing a LeetCode tag and learning how to solve problems associated with that tag. If we can do that with one tag, we can do it with two tags, then three tags, and so on. Eventually we’ll reach the point where if we know which concept a problem requires, and if the problem has a reasonable difficulty level (i.e., Easy or Medium), we’ll have a good chance of solving it. No flashes of insight required.

This year, I’m publishing a series of tips for effective LeetCode practice. To read the tips in order, start with A Project for 2023

LeetCode Tip 2: A Sample Problem

By Duncan Smith Leave a Comment Jan 18 0

LeetCode 2023

To help make the upcoming tips less abstract, I’m going to start with a sample problem that I’ll refer to when needed: LeetCode problem 704, Binary Search. I chose binary search because it has a short implementation that uses only basic language features, but even experts have trouble getting it right.

« Continue »

LeetCode Tip 1: Why LeetCode?

By Duncan Smith Leave a Comment Jan 11 0

LeetCode 2023

We’re going to be covering LeetCode tips in the coming year. But before we get to the tips, I’d like to discuss why I chose LeetCode as a study topic, so you can decide if this year’s project is right for you.

I chose LeetCode because:

  • It focuses on coding interviews: There are several reasons you might want to study algorithmic coding problems. But for this year’s project, we’re going to focus on one: Preparing for a coding interview. We won’t ignore the other reasons entirely, but the focus will be on the practical goal of getting better at the coding interview process. This aligns with LeetCode’s strengths, as compared to a competitive programming site like Codeforces or a general textbook like Introduction to Algorithms.

  • It has an active community: There are other sites for building coding interview skills. But LeetCode’s popularity gives it some advantages compared to other sites: It has an active discussion section for every problem, two weekly contests generate a regular supply of fresh problems, and the LeetCode company receives enough income to keep the site up to date. There are many programmers with the goal of preparing for interviews, and we might as well go where most of them are.

  • It supports regular practice: The way to get better at coding interview problems is to write code and see how it performs on tests. This matches the core LeetCode practice loop: Read a problem, design and implement a solution, run it on test data, and try again (or move on to the next problem).

The tips we’ll be covering this year promote two goals: 1) Practicing coding interview problems, and 2) Understanding the solutions to these problems. LeetCode has a similar structure. The online judge supports practice. And to help with understanding the solution, each problem gets a throughout analysis by LeetCode in the official solution and by community members in the discussion forums.

  • « Previous Page
  • 1
  • …
  • 5
  • 6
  • 7
  • 8
  • 9
  • Next Page »

Stay in the Know

I'm trying out the latest learning techniques on software development concepts, and writing about what works best. Sound interesting? Subscribe to my free newsletter to keep up to date. Learn More
Unsubscribing is easy, and I'll keep your email address private.

Getting Started

Are you new here? Check out my review posts for a tour of the archives:

  • 2023 in Review: 50 LeetCode Tips
  • 2022 in Review: Content Bots
  • 2021 in Review: Thoughts on Solving Programming Puzzles
  • Lessons from the 2020 LeetCode Monthly Challenges
  • 2019 in Review
  • Competitive Programming Frequently Asked Questions: 2018 In Review
  • What I Learned Working On Time Tortoise in 2017
  • 2016 in Review
  • 2015 in Review
  • 2015 Summer Review

Archives

Recent Posts

  • Do Coding Bots Mean the End of Coding Interviews? December 31, 2024
  • Another Project for 2024 May 8, 2024
  • Dynamic Programming Wrap-Up May 1, 2024
  • LeetCode 91: Decode Ways April 24, 2024
  • LeetCode 70: Climbing Stairs April 17, 2024
  • LeetCode 221: Maximal Square April 10, 2024
  • Using Dynamic Programming for Maximum Product Subarray April 3, 2024
  • LeetCode 62: Unique Paths March 27, 2024
  • LeetCode 416: Partition Equal Subset Sum March 20, 2024
  • LeetCode 1143: Longest Common Subsequence March 13, 2024
Red-Green-Code
  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter
Copyright © 2025 Duncan Smith