How a year-long LeetCode habit upped my professional game
The cult of live-coding and algorithm job interview questions is still alive and well at a ton of companies. Perhaps candidates must demonstrate they know how to transform a binary tree or how to write a heapsort. But is it useful to know this stuff beyond interviews?
This idea that these complex (and boring) algorithms are useful to know just to pass interviews has undoubtedly caused a lot of developers to genuinely start to hate them.
Once upon a time, I went to LeetCode myself (one of the most popular platforms) to practice algorithm problem solving. Let me be clear: I was not doing this to practice for an interview. Further, I had no illusions about the fact that this type of problem-solving is quite different from the everyday work of a developer. Nonetheless, I quickly noticed that certain knowledge gaps started to disappear.
Motivated by this, I started to invest time there nearly every day; I’ve now logged more than 400 tasks as completed.
Let’s analyze each of the improvements I’ve mentioned and I’ll give practical advice for anyone looking for the same results.
1. More attention, fewer bugs
In our line of work, it’s very useful to develop a habit of asking ourselves questions like, “Will my function fail when the input data is very large? What will happen if it’s empty?”
One reason I really love LeetCode problems is because they sort of gently force you to consider (if not actually write) different possible test cases. The platform not only provides test coverage for simple, common cases, but also for all sorts of negative cases, as well as cases with a large input (taking into account, of course, the constraints).
At first, taking edge cases into account can actually be annoying, because sometimes it seems you’ve got all the general cases in mind, but then 1 test out of 40 fails. That’s the case that forces you to rewrite half of your code. When a task is difficult, and when this fail is coupled with red “Wrong Answer” text blasting back at you—it’s not always so fun.
But once I had more completed challenges under my belt, I began automatically analyzing constraints, and coming up with (and checking) more test cases before submitting.
My tips practical tips for honing your code attentiveness:
- Think about how problem constraints might affect a potential solution. (If an array can have a billion elements, a brute-force solution is unlikely to work.)
- Analyze the time and memory complexity of your solution using big O notation. Don’t bother looking at the runtime percentages that LeetCode displays after submission. They’re useless: this article explains why.
- Don’t just consider general test cases while checking your code, try to keep negative cases in mind, too.
In real life, the words “Wrong Answer” aren’t displayed whenever we make a mistake.
But even still, these practices did start to show themselves, not only when solving algorithmic problems, but at work and when writing my own projects.
2. Coming up with solutions and writing code faster
I didn’t expect this, but after about six months, I was pleasantly surprised to find that my speed had improved.
In fact, tasks with medium-level complexity took about 50% less time compared to when I started.
How? Even across a variety of tasks, common patterns and approaches to solving them still become clear. Going through a binary tree is a good example; even after a few months of intermittent work with those problems, you could practically write this algorithm with your eyes closed.
Additionally, beyond sheer coding speed, I also noticed a speed increase just for choosing an approach to solve a problem. (Just an example: if a problem is unclear and it has an array as input data, you could try to sort that first.)
Here are my speed-developing tips:
- Go at a reasonable pace and take your time mastering a particular topic. A possible example: for trees, you might first solve seven easy-level problems, then ten medium, and then five hard ones, and only then move on to, maybe, lists.
- Don’t forget to review old topics. Even if you’ve mastered trees, do a tree task every couple of weeks.
- Try to solve an “easy” task again, but give yourself a time constraint. Artificial difficulty can sometimes significantly increase performance!
3. No fear of hard tasks, and easy ones are breezy
Again, I’m not trying to convince anyone that algorithm knowledge is something that everyone needs in their daily work. For people working with complex material and optimizations, sure, it may be necessary.
That being said, as a front-end developer, over the past year, I’ve needed to use complex, non-trivial algorithms a handful of times. (The most difficult cases were related to client-side graph visualization.)
Even though this was not an everyday thing, if I had encountered problems like that before my year of LeetCode, perhaps I would’ve been a little more timid, with extra time (and nerves) wasted in the process.
Thankfully, because of my experience, “new and scary” was “interesting and intriguing” instead.
I don’t even spend one second thinking about how built-in JS methods work: I know exactly how to sort characters in a string in descending order, what .push() returns, and whether .slice() or .splice() mutates the original array. Sure, it’s not exactly “algorithmic” knowledge, but in the process of solving these challenges, you’re forced to get a real grasp on these functions.
Here’s how you can start feeling much more confident no matter the task difficulty level, (and maintain progress momentum):
- Some complex tasks can be quite wild, so don’t be upset or give up if you can’t solve one!
- Use it or lose it. Try applying what you’ve learned at work: for example, when appropriate, try using the Set data structure instead of Array.
- If you’ve decided to do this with a new programming language, start by solving the simplest problems first. You’ll grasp the syntax and features of the language much faster than if you just read theory.
4. You’ll become a master of clean code and explaining your solutions
I’ve encountered folks with the opinion that sites like LeetCode are bad because they allow you to write code as “dirty” as you’d like; basically, as long as it works, you can pass. That’s true, sure, but then again, these aren’t really intended to teach a person to write cleanly and clearly.
These challenges still present an awesome opportunity to learn how to improve your code and to better explain your solutions.
On these sites, there is basically always a section where people can post their own solutions. Sometimes there is an option to rank them, and the most understandable, well-explained solutions go to the top of the feed.
After I began to clarify incomprehensible and complex problems for myself by reading the explanations of experienced people, my learning process accelerated. I started posting my own solutions, too, since I realized that it’s helpful for other people when solutions are explained in detail. I began to work on detailed descriptions of the solutions, and also on the cleanliness of the code. After all, it’d be a shame to share “dirty” solutions with your fellow learners! I wanted my version to be as clear and readable as possible. Subsequently, I noticed that I began to transfer this principle to work tasks. And it’s also helped me to explain my solutions to my colleagues better.
So, how can you improve your coding cleanliness and explanation skills?
- Post your solutions (just try to make the code as clean as possible first).
- Practice writing explanations for your solutions, and try to write so even beginners can understand.
- When solving a problem, look at other posted solutions. You’ll not only pick up some new approaches, you’ll be able to see how thought-out explanations are written. (And try not to get demotivated about how awesome others’ descriptions might seem–remember, you’re improving.)
5. Developing self-discipline
In any business (whether cross-stitching, football, or solving algorithmic problems) motivation and regularity are the key to everything. If you’ve displayed the motivation to open LeetCode for the first time-then your next step is achieving regularity.
To do this, I made problem-solving a habit and firmly decided that I’d find time for this activity every day for at least for half an hour. When a streak keeps going for a few months, it becomes a shame to miss a day.
It’s important to find a time of day that suits you best. I solved problems every day in the morning before my work, but it could be an evening thing, too. Choose the most convenient time based on your level of intellectual activity during the day.
A few tips:
- Don’t try to solve a lot of complex tasks every day, you’ll just burn out. Increase difficulty gradually and devote a set time to tasks (for example, forty minutes a day.)
- Track your progress. You could keep a calendar and mark each day you tried to solve a problem. When motivation is fading, take a look to see how far you’ve already come.
- Never compare yourself to others. Someone’s solution may look much better than yours, but how can you know how many years that programmer has spent solving algorithms?
- Give yourself daily praise: once you begin a day, you already start to know a little more than yesterday.
What have I really learned?
During this year, I realized that algorithmic problems aren’t some silver bullet, but they can still make writing routine code an automatic process, remove the fear of tough tasks, and teach you to constantly think about different test cases. Posting solutions, and trying to keep them clean and detailed, allows you to pump up your code-explanation skills.
Bottom line: even if your goal isn’t to ace a live-coding interview, the skills from regularly solving problems like this will help you with any job.
Still in doubt? Just try 3 days and see how it goes.
Evil Martians is a product development consultancy with offices around the world—and we get things done. Got a project in need? Contact us for an extraterrestrial consultation.
For more helpful articles, follow us on Twitter and subscribe to our newsletter below!