Competitive programming is fun, rewarding and awesome. It helps you to become a better programmer, writing efficient software, and much more. Additionally, it is asked (depending on role) heavily in job interviews at most of the IT companies.
For past one year I’ve been doing at least one question on Leetcode (a competitive programming platform) a day and now, in the retrospect, I can see the benefits. I’m going to share my experience and strategies I followed that helped me to make most out of time invested in doing competitive programming.
I believe someone starting out and struggling with competitive programming shall benefit from this post. These learning strategies are transferable and could be used to learn other skills. Yeah! competitive programming is a skill you get better at it with time and directed efforts.
Competitive programming is not trivial. It takes time, energy, and efforts to become good at it. Be kind on yourself. Do not feel demotivated when you are solving problems, and unable to do so. It comes naturally to some people, and for the rest, it comes with effort and time. Be assured that staying at it for some time with the right strategy is going to help a great deal in becoming good.
Stick to a topic & iterate
I was haphazard in my approach when I started doing Leetcode - doing random problems with no specific direction to follow. With time I realized that this approach is limiting, and at the end of the day I’m not making me any real progress. Remember just solving questions isn’t same as making progress.
The strategy I followed after this realization was to pick a topic - arrays, dynamic programming, graphs, trees, etc, - and cover problems for that topic, gain confidence, and moving on to the next topic. Remember, it is not about solving all the problems but just enough for you to gain confidence.
Doing questions for a topic just once is never enough (wasn’t for me). There are always some concepts which warrant more understanding that is gained after covering the other topics. Hence, doing multiple iterations over topics is always a good idea.
Dissect a problem
This advice seems obvious but it is possible to forget it at times. Solving a problem is simply not enough, chances of you seeing the exact same problem again are low though encountering some variation of it is highly likely.
Therefore, do not only concentrate on solving the problem - go through all the constraints, understand how they shape the approach and speculate over how the approach would change when they are tweaked, etc.
It is okay to see the answer
Consider this, you’ve spent hours trying to come up with a way to solve the problem but haven’t found a solution yet. It is OKAY! to look at the answer after you’ve exhausted all the approaches you could think (personally I do it after an hour of intense trying).
Even after you’ve solved a problem it is always a good idea to go through the approach used by others. Let us be honest, there are people who are much better at this than you are right now, and would definitely learn more by going through the alternate approaches.
Do more of what is not easy
It is easy to make yourself believe you are making progress by doing more of the topics/questions which you are comfortable. Though this approach isn’t going to take you where you want to reach. I’m not suggesting to start tackling hard problems on day one, real progress is made just out of comfort zone. Start with easy problems with eventually increasing the difficulty level. Again, don’t be too hard on yourself, it takes time :).
One of the good things about LeetCode is that it provides difficulty level tags which help to streamline the practice.
Identify the pattern
There are only a few algorithms which you need to know to solve more than 90% of the problems. After solving like 20-30 problems from a topic you’ll have a sense of familiarity with the problems. And there is a high chance that the problem is some variation over one of the problems you’ve solved. Aim for this familiarity when you are starting out, and do not try to learn all the algorithms that will happen in time.
In case, you are doing competitive programming to prepare for job interviews you do not need to know all the algorithms to ace them. Only knowing popular ones with possible applications is enough. Gayle covers this aspect very well in her book Cracking The Coding Interview, and I would highly recommend this book to prepare for job interviews.
Finding time to do competitive programming every day is hard, especially if you are a graduate student like me or have a full-time job. So, it is beneficial if you make a habit out of it and given the return it is a good habit to follow.
The strategy I followed, to make competitive programming a habit, comes from a productivity hack which suggests you to gamify life. I started with making daily commits to my leetcode repo on GitHub and eventually, my aim in life became to keep the green light (contributions) going uninterrupted as long as I could. It is easy to cheat yourself into keeping this going by doing easy problems or making rogue commits but in the end, you’ve to be honest with yourself. Remember you are doing this for yourself.
My GitHub contribution graph over the past year
Hands down job interviews are hard, stressful and take up a lot of energy. It is a performance where you are expected to present your best self. It is one thing to solve LeetCode/Competitive Programming in a pressure-free and low stake environment vs. solving a similar problem in an interview setting. Whiteboard interview is the standard interview process across the IT industry and most of the companies - big or small - follow it to make hiring decisions.
** No comments from my end on whether whiteboard interviewing is a good parameter to evaluate a candidate **
The best thing you could do to perform well in these interviews is to practice writing code on a whiteboard. No, seriously do it and you’ll realize it is not as easy as it sounds. Therefore, practicing writing code on a whiteboard is really important. Aim for writing code as close to real code. Though using short forms such as using
vector<int> is fine.
Thanks for reading till the end, and hopefully you found it useful.
Thanks @Kashfi for the suggested changes.