Red-Green-Code

Deliberate practice techniques for software developers

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

LeetCode Tip 23: Learning Algorithms and Data Structures

By Duncan Smith Leave a Comment Jun 14 0

LeetCode 2023

Most LeetCode problems require some knowledge of algorithms and data structures. But LeetCode problems are also a way to learn algorithms and data structures. So there’s a symbiotic relationship between the problems and the knowledge required to solve them.

Reading a textbook chapter about binary search will help you understand the principles behind it, how to analyze it mathematically, and the steps required to implement it. But it’s difficult to understand binary search well without solving binary search problems. Solving a simple binary search problem like LeetCode 704 is a good way to learn the fundamentals of the algorithm. From there, you can move on to harder problems where you have to integrate the binary search algorithm into a larger solution. As you’re solving a harder problem, you might go back to the textbook description of an algorithm to clarify the details, and then use that information to improve your solution. In this way, you can set up a virtuous cycle where solving problems helps you understand the algorithm, and the algorithm helps you solve problems more effectively.

Writing detailed model solution descriptions can also help you learn algorithms and data structures better. Just as writing a model solution clarifies your understanding of a specific LeetCode problem, it can also help you understand the general principles behind an algorithm. As you write your solutions, use correct terminology and explain how your solution applies a general algorithm to the specific problem you’re writing about. This will make it easier to move on to the next algorithm in a topic-wise list, since your algorithm skills and knowledge won’t be closely tied to one problem.

Besides applying an algorithm to a familiar problem, another key LeetCode skill is selecting the correct algorithm for a problem you haven’t seen before. As you learn algorithms and write solution descriptions, you can take notes from that perspective. For example, you can remind yourself that when the input data for a problem is sorted or can be sorted, consider using binary search. When you’re solving a topic-wise list of problems, you aren’t practicing this skill directly, since you already know which algorithm the problems require. But even with this type of practice, you can look for similarities between the problems, and include these in your notes. Then, when you need to select an algorithm for an unfamiliar problem, you can look through your list of heuristics to get ideas about which algorithm to use.

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 22: Remembering vs. Understanding

By Duncan Smith Leave a Comment Jun 7 0

LeetCode 2023

A common criticism of algorithmic coding interviews is that they select for people who have “memorized a bunch of obscure algorithms.” In this view, recent computer science graduates have an advantage over experienced developers because they can still remember the material from their algorithms courses. And candidates can beat the system by memorizing a list of solutions and brain dumping the appropriate solution for the interviewer.

This way of thinking about coding interviews doesn’t make much sense once you have some experience with the process. Although interview problems may be difficult, the algorithms they require are hardly obscure. Algorithms that use hash tables, binary trees, and breadth-first search are commonly taught to undergraduates. But these basic principles can be combined in infinite variations, so memorizing solutions isn’t a very helpful approach. As for recent graduates, they may have some advantage. But given the low pass rate for entry-level interviews, it’s clear that having taken an algorithms course in the past few years is hardly a silver bullet for coding interview success. Most candidates at any level of experience have to prepare for interviews, beyond what they do in their daily work.

The grain of truth in this view of coding interviews is that interviews are not a pure intelligence test. They require domain knowledge, not just problem-solving skills. It’s possible to work as a programmer without ever studying algorithms. In fact, it’s even possible to work as a programmer without remembering programming language syntax or libraries. You can always look things up on the fly in the documentation or Stack Overflow, or have a chatbot write code for you. But you can’t pass a coding interview this way (at least the in-person variety). So for coding interviews, and efficient real-world coding, you do have to remember some information. It’s not enough just to understand concepts.

Since we can’t just memorize all the solutions, but we also don’t have time to figure everything out from first principles during the interview, we need a more nuanced approach to learning this material. Fortunately, we have already covered the necessary tools in previous tips. The key is to maintain the right balance between remembering and understanding.

To do this, we have to use the spaced repetition process correctly, in particular when it comes to interval lengths. Although you must set intervals lengths according to certain heuristics to make the process work, there’s also a risk that interval practice will push you towards memorizing a solution. In the early repetitions of a solution, you have to remember a few things: the general approach that a problem requires, the details of an algorithm, and any language syntax or libraries that you don’t already know from other problems. This type of remembering is good. It’s exactly why repetition is a good way to improve your skills. Repeating the solution with short intervals shows you what you need to learn.

The problem occurs when you try to move beyond short intervals and you get stuck. According to the spaced repetition process, when you have trouble solving a problem, the correct approach is to shorten your practice interval and try again. This may in fact be necessary. But as you think about the right interval to use, make sure you’re not using repetition as an alternative to understanding. Repetitions are good for identifying areas you don’t understand yet, and for reinforcing things you already know, but they’re not good for learning things in the first place. To do that, you need to go back to your model solution, identify the gaps in your understanding, and do the research or experimentation required to fill them. Only after you finish that process does it make sense to go back to repetition.

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 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.

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

  • Will AI Coding Assistants “Deskill” Us? January 30, 2026
  • Stateless by Design: How to Work With AI Coding Assistants December 31, 2025
  • 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
Red-Green-Code
  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter
Copyright © 2026 Duncan Smith