Lots of credit to Matthew Zygowicz, he is the one who introduced me to this idea.
Leetcoding or ‘whiteboarding’ style problems are incredibly common in the software space. In fact, it’s quite controversial as well. Anyone who has been in the software development field long enough knows that these types of problems will be encountered sooner or later. Especially when interviewing for a job. Hiring is an incredibly hard process and every company has a different approach to it. However, these types of problems tend to be similar between interviews. For a long time, I was against these types of problems because I honestly didn’t believe they measured anything of value for a candidate, insted they only placed them under more stress. However, when it comes to these types of problems in a live interview setting, I’ve been pleasantly surprised with how beneficial I’ve found them, even as an interviewee.
Why should I practice leetcode style problems?
Leetcode-style problems have many benefits aside from the technical learnings they can provide. These types of problems tend to force developers into choosing one among many different paths of implementation. These are great practice for learning new algorithms, data structures, and approaches to solving problems.
Leetcode problems, especially ones you haven’t seen before, can be approached very similarly to real software problems. This process of breaking down and understanding a problem is absolutely crucial in a real-life setting, and it’s where these types of interviews begin to shine. This process can be used in your daily work and it can help any developer become better at their job. Additionally, through the process of breaking down a problem, you begin to understand the pros and cons of the different solutions available and learn how to communicate them. Whether or not you are looking for a new role, I believe this practice is very beneficial. It has recently become commonplace in my daily routine.
My process for breaking down a problem and how it relates to the real world
I've never read ‘Cracking the Coding Interview’, or any of those interview prep books. I went straight to leetcode problems and asked a colleague for advice on how he approached these types of problems. Some of these may seem repetitive if you’ve read them before, but learning this process was a novel experience for me. I encourage you to struggle with the problems a bit to solidify this process for yourself.
Re-read the problem a couple of times aloud
As you read the problem aloud, go through the parts you don’t understand or need clarification on. In an interview setting, this could prompt an interviewer to respond and help you clarify. However, in a practice setting, this is the sort of thing you can practice, research more, and think about in depth.
In a real-world setting, this builds trust amongst your team and any parties involved in the problem. That’s because it shows you're truly trying to understand the problem and even uncover the different 'unknown knowns', or even 'unknown unknowns'.
Try to identify the ‘bounds’ of a problem
Every problem has boundaries. There are parts of a problem you may never have to come across, and parts that’ll you need to factor in when coming up with a solution. This is key, eliminating and identifying boundaries can drastically change how you approach a problem.
Over-engineering is very real everywhere you go but can be eliminated by properly identifying and expressing the boundaries of your problem. By narrowing the scope, you narrow your solution and can provide a solution quickly and effectively.
Sometimes these bounds are a given. However, it’s best to try and understand them yourself and double-check against what is given in a problem.
In a real-world scenario, this may mean identifying dependencies on other teams, or bottlenecks that can be a risk to a project. Maybe you are forced to use a certain version of react on a project and need to ensure that you’re designing your components just for these bounds.
Start fixing the problem at a high-level
In most coding interview scenarios this can just be pseudo code or discussing how to approach it.
I’m a javascript developer by trade, so I tend to just start coding, but very crudely. In some cases, I find it hard to write pseudo code, but I can write crude javascript and revise it later on.
In the real world, this can be flowcharts and documentation on how you want to approach the problem. This is key, because in most instances you’re part of a team, working with others. This documentation ensures everyone is on the same page and understands how the problem will be solved. Additionally, this can help the team to find holes in a design, and address them before it's too late.
Solve the problem in a way you understand
During an interview, you’re pressed on time, so unless you’ve seen this type of problem before, 90% of the time you won’t have a perfect solution right away. However, through this step, or step 3, you may identify ways to improve your solution.
In a real-world scenario, you can’t account for every efficiency and improvement needed from the early design process. There can be too many variables at play and more often than not, getting a functioning solution is often the best outcome.
Remember how I said to identify the unknown knowns? This is where some of those learnings can come into play. You may have a gut feeling that a certain process will take longer, but the time needed to improve it isn't worth it for the time being. Identifying these processes and stating them clearly is important if you want to have a place where you can check things later on, in case you encounter any issues.
Improve on your problem or state where you think improvements can occur
Typically by this stage during an interview, you’re running out of time. But that doesn’t mean you can’t identify where improvements can be made and certain bottlenecks can occur.
In a real-world scenario, once you’ve shipped a solution you can get feedback and understand how to proceed. Maybe the customers love it and now you can go back to improving what you think could benefit them. Or, worst case scenario, they don’t like it and you go back to the drawing board. If that happens, you won’t feel so bad letting go of a problem now. It’s better than thinking about all the hours you lost optimizing a workflow.
How can leetcode problems help me as a developer?
The process of breaking down and understanding the boundaries of a problem can be applied to virtually every piece of code you write. Even something as simple as creating a react UI component can fall into this. Like, figuring out how this component is designed, what logic it needs, and how it’ll be used. If you know this component will need to be unit tested, you may write it differently in order to make the testing easier.
Secondly, almost every developer will work on a team at some point in their career. A commonly overlooked skill is communication. Being able to concisely explain your ideas and different concerns you may have about a design to your team is crucial. This is a skill you can learn and practice through leetcoding. While you may not be talking to someone when practicing, getting into the habit of speaking out loud and act like you’re explaining your thought process to someone, is great practice for the real world. Additionally, in the real world, most designs will have a system and maybe business constraints that will force you to design your software to adhere to those constraints. Being able to convey these constraints to others, makes sure everyone is thinking along the same lines and working on a solution collectively.
Finally, the reality of software development comes with a lot of repetitive work. Developing a truly new and innovative project is not something that happens very often. It can happen, but that usually doesn’t account for the majority of the code written. One issue with working on similar problems over and over is that you can develop ‘blinds’. Ultimately, in the eyes of a hammer, everything looks like a nail. Leetcoding problems help you think about problems with a tool belt, instead of using one tool to approach a variety of problems. Leetcoding will challenge you to see problems you’ve never seen before and force you to use strategies that are the most efficient to solve them. Strategies you may have never seen before and some of you may need to learn from scratch.
Conclusion
Leetcode style problems have become a standard for many when preparing for new jobs and job interviews. They’ve been glamorized by some in the tech world, and they’re hated by others. However, practicing leetcode problems of all levels has surprising benefits. It’s more than learning algorithms and data structures. Regularly practicing leetcode problems can teach you process-related skills and enhance your skill set. Both of these benefits extend to your daily life and work, ultimately hardening your skills and improving the things you build daily.