Red-Green-Code

Deliberate practice techniques for software developers

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

LeetCode Tip 21: Learning Language Libraries

By Duncan Smith Leave a Comment May 31 0

LeetCode 2023

Gaining fluency in language syntax is the first step in getting better at expressing the solution to an interview problem in code. But even in a coding interview, you won’t be expected to implement everything from first principles. It’s true that if the interview question asks how to implement a hash table, then you’ll have to understand the internal details of hash tables. But if you just need a data structure you can use to insert and retrieve in average O(1) time, you can use the one provided by your language’s standard library.

For coding interview preparation, the difference between built-in language features and a language’s standard library isn’t too important. The best approach to learning either one is to solve problems and read editorials until you encounter a new concept, and then focus on learning that concept. At some point, you’ll encounter features that are part of your language’s standard library, like the C++ Standard Library or the Java Class Library.

Just as with language syntax, the goal for learning a standard library is achieving fluency. Although you can do well in a coding interview even if you forget exactly how to initialize and use a hash table, being fluent in a language library will speed up the coding process and give you more time to think about the hard parts of a problem. It also shows that you have experience using a language. Interviewers often let candidates choose which language they want to use, so they expect candidates to pick one they’re fluent in. If a candidate isn’t fluent in their self-chosen language, the interviewer might wonder how much programming they actually do on a daily basis.

As you solve interview problems and study solutions, you’ll learn which library features are useful for solving those types of problems. Using code from your model solutions, look for patterns in how features are used. You will only need a small subset of the library, so focus on learning this subset well. Within the useful subset, find a consistent way to use library features, which will make them easier to remember. If a library gives you multiple ways to do the same thing, see if you can solve problems using just one of them.

Just as you can write model solutions to document your best approach to solving a problem, you can also write model code for a library feature. Rather than a full solution, this model code is just a block of code with one purpose. For example, some problems can be solved using a priority queue, which many languages offer as a library feature. A priority queue (also called a heap) provides an efficient way to retrieve the maximum (or minimum) item in a collection. To use a priority queue in a solution, you need to know how to initialize it as a max heap or min heap, insert a new item, peek at the min/max item, remove the min/max item, and check the size of the collection. Through practice, you’ll probably find that these are all you need from a priority queue, even if your language offers more properties and methods. So your model code only needs to show how to use these facilities.

Once you write model code for a library feature, you can use it for reference, as an alternative to looking at the library documentation. As you repeatedly do this, you’ll internalize how the feature works, until you reach the point where you don’t have to refer to any model code for that feature.

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 20: Learning Language Syntax

By Duncan Smith Leave a Comment May 24 0

LeetCode 2023

Succeeding at algorithmic coding interviews requires learning about algorithms and data structures. But it’s not enough just to know the theory of algorithms. You also have to implement them quickly in a real (non-pseudocode) programming language. If you’re writing code on a whiteboard or a plain text editor, your code has to be good enough to impress the interviewer, but you can take a few shortcuts with syntax. If you’re using an online judge like LeetCode that compiles and runs your code against test cases, the syntactical standards are higher.

Learning a programming language to solve LeetCode problems is both easier and harder than learning a programming language to solve real-world coding problems. It’s easier because you don’t have to learn everything about the language and its associated infrastructure. For a real-world problem, you might have to learn a front-end language, a back-end language, libraries and frameworks, a database, pseudo-languages like HTML and CSS, and other details that go into creating a working software solution. For a LeetCode problem, you only need to learn a small subset of a programming language and its libraries. And you don’t have to set up a programming environment or automated tests. You just type code into a box and click a button to run it. Everything else is handled for you.

On the other hand, many programmers find interviews to be more challenging than their daily work. Even if we ignore the challenge of learning algorithms and data structures (see the previous tips for more on that) there is still the challenge of coding on demand under both time pressure and the watchful eye of the interviewer. To do well in these conditions, you need to work on language fluency.

The way to improve your programming language fluency is to practice the syntax of a language the same way you practice implementing algorithms. If you’re working on a problem that asks you to solve a 2D maze and you have trouble representing the maze as an array, study how your language handles arrays. Isolate that component of the problem, separating it from the maze-solving algorithm, and practice until it becomes second nature. Make sure you can address the cell in a particular row and column, move North or West or Northwest in the maze, and check whether you are out of bounds. Don’t return to the maze algorithm until you’re clear on the array syntax.

The goal of practicing language syntax is to reach the point where you can express concepts in code as easily as you can write pseudocode, math equations, or diagrams. You never want to know the solution to the problem but be unable to write the correct keywords and tokens to implement it. Ideally, if you can think of the pseudocode for a solution, your fingers should be able to type the equivalent code without much intervention from your brain.

Besides language syntax, you also need to practice your language’s standard library. We’ll cover that in the next tip.

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 19: How To Use a Problem List

By Duncan Smith Leave a Comment May 17 0

LeetCode 2023

To use LeetCode effectively, you have to find and practice model problems. A good model problem is one that you haven’t solved too many times, is the right difficulty for your level, and focuses on a core concept rather than extraneous details.

Once you find a problem that meets these criteria, you can learn a lot by repeatedly solving it using a spaced repetition process. But even a great problem doesn’t stay useful forever. It eventually becomes so easy that you get nothing out of solving it again. Or after a few repetitions, you might find that it still doesn’t make sense to you because it requires a concept that you haven’t yet learned. In either case, you need a list of problems that you can draw from when you need a new one to practice.

You don’t have to look far to find a problem list. Since the goal is to master a set of concepts, it’s fine just to use the LeetCode problem page, where each problem is tagged with a concept. But with new problems being added every week, the number of problems in the official LeetCode list can seem overwhelming. The solution: use a problem list where someone has filtered the full LeetCode list down to a manageable size. Two examples are Tech Interview Handbook, the source of the well-known Blind 75 list, and NeetCode, which includes Blind 75 and other lists.

Even if you use a curated list, it’s still good to filter it according to your own unique criteria. Unless you have an expert tutor choosing a problem specifically for you, a list can only give you problems that are good for the average LeetCode user. A problem may still not meet your needs at a specific time on your practice journey. So, as you’re making your way through a list of problems, don’t worry about skipping a problem if it isn’t what you need.

Problem lists have different options for which problems to solve and in what order. But one option most of them provide is topic-wise practice. If you have a flexible schedule, this tried-and-true approach works best, along with spaced repetition. It’s the most straightforward way to learn each concept.

To use topic-wise practice, first decide on a concept to practice — for example, binary search. Then pick a problem list and find the recommended set of problems for that concept. Look through the list and find a problem to start with. You can skip problems if you already have experience with the concept, but when in doubt, start with the first problem. To practice it, use spaced repetition intervals: Start by practicing it every day, then every 2 days, 4 days, and so on. You can skip interval lengths if the problem is too easy. Once you get past the 1 day interval, you’ll need something else to practice. So pick the next problem on the list.

As you build out a spaced repetition schedule, you’ll generate a set of problems that cover a single concept and are spread out in some spaced distribution, with easier problems using shorter intervals and harder problems using longer ones. Once you get to the Medium problems for a concept, you should have a good idea about the fundamentals of the concept, and you should be familiar with a few problems that cover the key insights for that concept.

As you get started on your second concept, you’ll adjust your spaced repetition plan. Rather than a set of problems covering one concept, you’ll mix in problems that cover different concepts. This is by design, since you want to continue repeating the original concept so you don’t forget it while you learn the new concept. Let’s say your second concept is hash tables. For some repetitions, you’ll solve problems from binary search, and for others you’ll use hash table problems. So you’ll be learning hash tables while keeping binary search fresh by periodically solving those problems. By continuing this process, you can make your way through the full list of concepts.

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 18: Learn General Skills From Specific Problems

By Duncan Smith Leave a Comment May 10 0

LeetCode 2023

Using a practice journal for your LeetCode practice helps you learn as much as you can from a single problem. This requires a different mindset than using a problem list from Tech Interview Handbook, NeetCode, or the Daily LeetCoding Challenge. When you use a problem list, your goal is to get a variety of experience from a set of problems. A practice journal, on the other hand, helps you learn one problem as thoroughly as possible.

You can learn a lot by working on one problem through multiple repetitions. Every LeetCode problem covers one or more common concepts. By repeatedly solving the same problem, you can focus on the concept rather than having to figure out a new scenario, as you would if you kept picking new problems. For example, there’s a binary search problem that asks you to add events to a calendar. The first time you solve that problem, you need to spend time understanding the scenario. But the scenarios in LeetCode problems are less complex than the associated algorithm. So it may take only one or two repetitions to master the scenario, at which point you can focus on the algorithm.

Although the scenario may be simple, it is still a useful part of the problem. Recalling the steps of an algorithm is difficult in the abstract. Studying algorithms with an associated a scenario gives your brain something to latch onto. When you encounter a similar problem, rather than having to recall “binary search,” you can instead recall “how to add an event to a calendar without double booking.” As you practice more model solutions for an algorithm, you’ll learn multiple scenarios that help you approach the algorithm from different angles.

Practicing the same binary search problems multiple times doesn’t directly teach you to solve new binary search problems. But it’s a prerequisite for that skill. It helps you master binary search and several associated scenarios. When you encounter a new problem that tickles your binary search sense, you can focus on the specifics of that new problem, confident that you have mastered the implementation.

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 17: What To Write in Your Practice Journal

By Duncan Smith Leave a Comment May 3 0

LeetCode 2023

A key part of effective LeetCode practice is keeping a practice journal. Although LeetCode automatically tracks your solution submissions and can show you your previously submitted code, a journal gives you a more customized record of your practice sessions. You can use this to focus on the areas you need to study most.

In its most basic form, a practice journal is a list of time-stamped entries at the bottom of your model solution document. Whenever you repeat a problem, add the current date and some information about your practice session. At a minimum, write one sentence explaining the result. For example, “Solved it easily” or “Solved most of it, but got stuck on a few edge cases” or “Off by one in the binary search.” Then, if you find yourself repeating the same comments the next time around, you know where to target your practice efforts. Even a small journal entry like this will help. But with a few additional minutes after each repetition, you can get even more out of your journal. Here are two categories of notes to include.

First, you can record spreadsheet-style data. It’s best if you use an actual spreadsheet for this, so you can write formulas to calculate some fields automatically. Some ideas for what to record:

  • Timestamp: When you practiced.

  • Practice time: How long you spent solving the problem. You should observe this time decreasing as you get better at a problem.

  • Days between repetitions: Calculate the number of days since the last repetition. Use this with your spaced repetition system to ensure that you’re practicing at the correct intervals.

  • Next practice interval (days): Decide what amount to put in this field based on how well you did for the current repetition. The more easily you solved the problem, the higher the number can be.

  • Days remaining until next interval: Calculate this field and use it to find a problem that’s ready to practice (pick the problem with the smallest number).

  • Accepted on first run (yes/no): Record whether you got the problem on the first try, or whether it took a few tries. For a canonical problem that you want to master, the goal is to learn it well enough that you don’t have to rely on the compiler or the unit tests to guide you in the right direction.

Besides the spreadsheet entries, free-form journal entries are also useful. The goal of this type of section is to self-evaluate how well you know a problem and which areas are giving you trouble. Include notes about any areas where you got stuck, even if you ended up solving the problem successfully. These notes can help you polish your model solution, turning it into a solution that is exactly customized for you. You can also find problem areas by looking for bugs that show up repeatedly in your journal entries. This is more efficient than going through previous code submissions.

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 16: The Daily Practice Process

By Duncan Smith Leave a Comment Apr 26 0

LeetCode 2023

A daily practice habit can help you improve, but not every daily practice routine works equally well. If done incorrectly, it can become more of a chore to check off your to-do list than a useful learning tool. As we have seen so far this year, the LeetCode practice process relies on choosing model problems, writing model solutions, and practicing them using a spaced repetition process. Here are two more key ideas to ensure that your daily practice routine works smoothly.

First, problem selection. As you are learning the set of fundamental LeetCode concepts, the best approach for problem selection is what competitive programmers call topic-wise practice. Using this approach, you don’t worry about how to find the correct approach for an unknown problem. Instead, you pick problems where you know which algorithm or technique to use, and focus on learning how to implement it. To ensure that you get a well-rounded understanding, choose problems that use the algorithm or technique in different ways. To find relevant problems, use LeetCode tags or curated lists like the ones on Tech Interview Handbook.

Finding topic-wise problems is also a good way to take advantage of the daily challenge. As you’re working on the daily challenge, look for problems that use a familiar topic in a new way. When you find a problem like this, add it to your topic-wise list. By collecting a few problems for each topic, you can learn it more thoroughly than you would just by practicing one problem on a topic and moving on.

The second key idea: Keep a practice journal for each model problem. When you repeat a problem, record the date and your observations about that repetition. If you had trouble solving the problem (even if you eventually solved it) isolate the part of the problem that gave you trouble and make a note of it. As you record your daily progress, also review your model solution. If you can update the solution to make the challenging part of the problem clearer, this is the time to improve the code, the description, or both. If you check your notes for the previous repetition and find that you got stuck on the same part, that’s a sign that your model solution is still missing something. After multiple repetitions of this process, your understanding of the problem and your model solution should converge until you have mastered the problem and there’s nothing more to add to your solution.

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 15: Daily LeetCode Practice

By Duncan Smith Leave a Comment Apr 19 0

LeetCode 2023

Doing the Daily LeetCoding Challenge gives you daily practice, exposure to new problems, and a community of fellow problem-solvers. But it’s possible to get caught up in the routine of solving each daily problem while missing critical aspects of daily practice. To see why, we’ll consider the goals of LeetCode practice.

As explained in that tip, it’s not enough just to practice a problem, or even multiple problems, every day. It’s better than nothing, but it’s inefficient and it increases the risk of getting stuck on a learning plateau. Instead, we need to focus on learning problem-solving concepts, as enumerated in the LeetCode tags. Each problem focuses on one or two concepts. Solving a problem helps to learn a concept, and learning the concept makes it easier to solve the problem.

Since the daily challenge problems are just regular LeetCode problems, they come with a list of tags. In recent months, the daily challenge organizers have also grouped problems into themes. So we’ll get a few days of stack problems, a few days of hash table problems, and so on. This is better than completely random problems, since solving multiple problems in a topic area helps learn that topic from multiple angles.

But the downside of the daily challenge approach is that everyone gets the same topic every day. If you have solved a lot of medium and hard dynamic programming problems, spending a few more days solving problems in that area may not be the best use of your time. And if you’re having trouble understanding how to use the union-find data structure to solve LeetCode problems, practicing it for a few days one week may not be enough time to make progress on learning that concept.

So you should think of the Daily LeetCoding Challenge as beginner mode practice. Though the problems may be hard, the practice process is rudimentary. To get the most out of daily practice, you’ll need to design a process that is more customized than the one that every daily challenge participant gets. In the next tip, we’ll see how to do that.

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 14: The Daily LeetCoding Challenge

By Duncan Smith Leave a Comment Apr 12 0

LeetCode 2023

Since April 1, 2020, LeetCode has been running a Daily LeetCoding Challenge. Every day, they designate one problem as the daily challenge problem. If you solve that problem before midnight UTC, it extends your daily challenge streak and you get some LeetCoins added to your account. Other benefits include contests, badges, and a monthly Discord study group.

This gamified daily challenge is a good way to make sure you don’t forget about regular LeetCode practice. Once you get a streak going, it gives you an incentive to visit the site every day and solve the daily problem. On Discord, the study group lets you chat with people who are also solving daily problems.

The daily problem is also a convenient way to pick which problem to solve next. Sites like Tech Interview Handbook and NeetCode have more sophisticated problem roadmaps. But you can’t beat the simplicity of opening LeetCode and clicking on the fire icon to open the daily problem. In recent months, the problems have even followed a weekly theme, which helps you practice a particular algorithm or technique a few different ways.

If you’re serious about practicing LeetCode and collecting model problems and solutions, you should approach each daily challenge problem as a potential model problem. As you’re solving a problem, consider whether it would make a good model problem. Is the problem slightly more difficult than you’re comfortable with? Does it cover a topic that you want to know better? Does it focus on the fundamentals of that topic rather than on extraneous details? And finally, is it a good problem that is worth writing up and practicing repeatedly? If it meets these criteria, add it to your model problem queue to consider when you’re ready to start a new problem.

Despite the benefits of the daily challenge, there are things to watch out for when integrating it into your overall practice system. I’ll cover those in the next tip.

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 13: Spaced Repetition Interval Lengths

By Duncan Smith Leave a Comment Apr 5 0

LeetCode 2023

When you use spaced repetition for LeetCode practice, keeping track of repetition intervals on your own is better than having practice software do it for you. Unlike vocabulary words, LeetCode model problems and solutions are complex, so you’ll only have time to practice a few of them per day. This gives you the time to consider the appropriate interval length and what your goals are for the current repetition. Here are some suggestions for what to focus on at each interval length.

0 days

It helps to practice a model solution even right after you finish reading it. If you stare at a solution for 10 minutes, then put it away and start typing it into LeetCode, you still probably won’t be able to recall the full solution from memory. You’ll have to use your understanding of the solution to come up with a working submission. As you try to reproduce the solution on day 0, you’ll notice which parts are harder than others. This will start the process of learning the solution, and it can help you find parts of the model solution that need to be updated with a clearer explanation.

1 day

The one-day interval works like this: You practice a solution on day 0, sleep for one night, and try to reproduce the solution the next day without looking at it again. This will expose different facets of the problem that you didn’t see the previous day. Sleeping is good for consolidating memories, but it also starts the process of forgetting. So at this interval, you may find that parts of the problem are difficult to remember. Recalling troublesome parts helps strengthen recall, and as on day 0, it can encourage you to make updates to the model solution description.

2-4 days

For the two-day interval, you practice a problem, skip one day without practicing it, and practice it the next day. For the four-day interval, you skip two days. The 2- and 4-day intervals increase the difficulty of remembering the details of a solution, but they are still short enough that you’ll remember most of the problem, including which algorithm you used and some parts of the code. But you may forget some implementation details if you haven’t practiced similar problems. This is a good time to think about how the algorithm works and how to apply it in more general cases.

8-16 days

At these intervals, you can forget major concepts required to solve the problem. So it’s important to slow down and avoid increasing the interval until you have mastered it at the current length. Since you’ll be practicing other problems in parallel, solutions to multiple problems can get mixed in your mind. You might recall a technique that worked on Problem A and mistakenly using it on Problem B. That provides an opportunity to learn how to map a problem with the solution that works for it, which is an important skill to have when you’re solving unknown problems.

32-64 days

With this amount of time between repetitions, you might completely forget a problem, almost as if you are seeing it for the first time. This shows that you are increasing the repetition interval too quickly. The 32- and 64-day intervals are a good time to make sure you have a solid understanding of every part of the solution, including how to pick the solution approach given the problem description, the high-level plan to implement the solution, any tricky details for particular steps, and finally all the low-level implementation details.

128-256 days

At very long intervals, the only options for solving a problem are 1) Retrieve the solution from your long-term memory, or 2) Figure out the solution from general experience. You won’t be able to rely on short-term memory from recent practice sessions. The goal is to use option 1. The purpose of model problem and solution practice is to learn canonical problems in such a way that you can implement them without thinking too much. For example, you should be able to implement the standard binary search algorithm without thinking about how to find the middle of an array, or considering the pros and cons of lo < hi vs. lo <= hi.

The 128- and 256-day intervals are not so much about learning a problem, and more about verifying that it’s really in your long-term memory. After some experience with the spaced repetition process, you should be able to work out every detail of a problem at the shorter intervals, and avoid lengthening the intervals too quickly. Then once you get to the longer intervals, you should always be able to solve the problem. If that works out according to plan, you can now archive the problem to make room for new 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 12: How To Use Spaced Repetition (Part 2)

By Duncan Smith Leave a Comment Mar 29 0

LeetCode 2023

As you use a spaced repetition process for LeetCode practice, there are more things to keep in mind than just reproducing the solution correctly. Here are more tips to get the most out of the process.

Make sure you’re practicing the right problem

Before you start spaced repetition practice, you need to choose a model problem and write a model solution. But it may take several repetitions to figure out whether the problem you selected is the best problem for your current level of mastery of a topic. If you write a detailed solution for a problem and refine it over several repetitions, but you still have trouble reproducing the solution, it may be best to leave that problem for later. Maybe the problem combines multiple techniques in a tricky way, or builds on fundamentals that you haven’t yet mastered. It’s fine to switch to another problem in the same area, and come back to the original problem later. Spaced repetition works well to strengthen your understanding of a topic, but it’s not designed for learning a topic from scratch.

Understand the solution rather than memorizing it

Another advantage of spaced repetition is that it tells you when you’re trying to memorize a solution rather than learning it. For short practice intervals (up to a few days), you won’t know for sure whether you really know a solution. Although you may succeed in reproducing it, this could be because you remember it from the previous interval. But as you increase the interval length, it becomes increasingly difficult to remember a solution unless you understand it (unless you’re using sophisticated memorization techniques, which are better for card tricks than programming). So once you get to a 15- or 30-day interval, you can be confident that you know how the solution works, not just how to reproduce the code.

Develop building blocks to use for other problems

Repeating a problem that you have already solved uses skills that differ from the ones required to solve an unknown problem. But the first type of practice can help with the second. For example, if you encounter an unknown problem that seems like it may need a binary search solution, that knowledge won’t help unless you can implement binary search. So as you write your model solutions, remember that you’ll need to use these solutions for other problems in the future. When possible, write them in a way that isn’t too specific to the problem at hand. Some competitive programmers use this approach by assembling a code notebook to use as a guide for implementing tricky algorithms. But interviewers generally don’t allow this type of notebook, since they want to see you write code yourself. So for interviews, it’s best to keep the notebook in your head.

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.

  • « Previous Page
  • 1
  • …
  • 4
  • 5
  • 6
  • 7
  • 8
  • …
  • 49
  • 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