So I just finished my 100th LeetCode problem, and I have learned a few things along the way. Well, actually I learned quite a lot. Let me tell you a little about this excursion.
A few months ago I unexpectedly came across a challenge on the internet which led to an opportunity for an interview with a FAANG company. I had never really considered applying for a job at a FAANG company, and to be honest have probably undervalued myself in thinking that I wasn't really FAANG material. But here I was with this interview coming up and not really knowing what to expect as an outcome. In my mind, this was a dream opportunity that I was facing. I didn't want to do bad in the interview, but I wouldn't be hurt over failing the interview either. After all, I wasn't really looking for a new job in the first place and really like my current job. Expecting that I was not at all prepared for this type of interview was a fair statement, but what I really needed was a deep dive self-assessment into my own programming skills.
Pre LeetCode Assessment
I consider myself mostly a self-taught programmer. I have never taken a course on algorithms & data structures. Yeah, I got a C in my Intro to Programming class in college, which was taught with Fortran (no, I'm not that old). I really don't recall learning any OOP from concepts from that course. I ultimately went on to study Applied Math in grad school where we were expected to know some basics of programming. In grad school I did a lot of numerical linear algebra and differential equations (lots of iterating over arrays to solve and eigenvalue type problems.)
In my professional career, I have done quite a bit of programming in Python. To get a taste of some of the things I have used Python to work on, I have written programs that interface with the OS and filesystem to read/write files, get data from REST APIs, interface with databases, and interact with web elements for browser automation. I have even written a couple of GUI applications and done some machine learning projects.
Up to this point, none of my professional programming experiences really required a deep understanding of fundamental algorithms or advanced data structures other than simple arrays and hash tables. Well, maybe it was a little more technical on the machine learning side of my projects, but my studies from Applied Math helped out there.
So here I've got a pretty good understanding of Python, and really nothing else more than an understanding of looping over arrays and look-ups in hash tables for my own logical algorithms that I could think up (or the usage of some pre-built library that solves my problem) for the projects that I work on. I know that there are things out there like linked lists, graphs, and such, but I've got some studying to do in those areas, and I need to study them quickly.
The first thing I did was buy the 6th edition Cracking the Coding Interview book by Gayle Laakmann McDowell. This book has a quick intro to some of the basic and fundamental data structures and algorithms that one might need for an interview, plus 189 practical coding interview questions with solutions. This was a great start. The book quickly helped me fill in some of the gaps I had in data strucutres. I quickly pored over many of the problems and solutions, picking up some good techniques to think about various problems and algorithms along the way. I did this for about two weeks before someone told me to check out LeetCode.
Getting Started With LeetCode
In late January 2021, I registered for a LeetCode account, and did the first couple of problems in their list of ~1800 programming problems. My first impression was that this was getting my brain working in an old familiar way that reminded me of studying and figuring out those hard math homework problems from grad school. These seemed like pretty good problems to gauge your readiness for a coding interview scenario.
Over the first couple of weeks of February 2021, I would find myself on LeetCode early in the morning or late at night hacking away on two, three, four, or maybe even five problems per day. On LeetCode, problems are rated as Easy, Medium, or Hard. I was doing mostly a mix of slightly more Medium than Easy problems, and then just a few Hard ones. I don't know how others on LeetCode feel, but I thought that some of the Easy's were probably more of a Medium, and some of the Hard's that I did really felt like they were easy.
I tried doing every problem all on my own first. Some problems I could solve on my own, and some problems I found that I had come close to the solution on my own, but need a little more help from the discussion board to push me over the edge.
I was really learning (maybe cramming) a lot on linked lists, some trees/graphs, and a lot of recursion/dynamic programming type problems.
Let's Try Competitive Programming
Besides general practice problems for computer programming, LeetCode also host weekly and bi-weekly programming contests. They are free to enter, and you can win up to 5000 LeetCoins (tokens only valid for redemption on LeetCode's own web store).
Why not join a contest? It can't be that bad, right?
Well, at 8:30PM on a Saturday night I started my first ever competitive programming contest on LeetCode. We were presented with four problems, and one and a half hours to solve them. I believe the breakdown was one Easy, two Mediums, and one Hard.
After about 30 minutes, I had successfully submitted a solution to the first problem. Just three more to go. For the next hour, I struggled to complete the next problem. I was close, but had submitted a couple of wrong solutions which come with a five minute penalty. Unfortunately, I finally submitted a successfull solution about two minutes after the contest ended.
So, how did I do compared to the others? Well, I thought it was a bit amusing. Check out the finish time of the top five participants:
That is 7 minutes and 2 seconds to finish all 4 problems.
It probably took me 7 minutes to finish reading the first problem to a point that I could fully understand what it was asking me to solve for.
So, maybe I don't have what it takes to be a competitive programmer at this point. But, I have entered into a few more of the contest, just to see how well I can do in a time crunch, and I have gotten better along the way. I still have only successfully submitted up to two out of four problems during these contests (came close to submitting three), but maybe one day I will earn that 5000 point top prize.
Interview Round 1
About two and a half weeks in and it was already interview day. I had completed about 65 problems on LeetCode. I had learned some new things in Python that I hadn't known before like how to efficiently use stacks and queues using something called a deque (pronounced like 'deck'). I had learned a lot of new thought techniques and using various types of algorithm strategies to solve problems (methods of searching and sorting can come up a lot, and it's good to know the tradeoffs of the different methods). But honestly I was still quite nervous about the interview and felt like there was so much more I needed to learn.
The interview came and went, and it really wasn't all that bad for 45 minutes of a coding interview. I don't think I knocked it out of the park, and it took me a bit too much time before things finally clicked and I really understood the problem. I left the interview wishing that I would have been faster at understanding the problem so as to have more time to think about the actual coding part, but the interview that I gave turned out to be good enough!
After, the first round interview, I knew there was more to learn, and I couldn't stop there. I have continued to push onwards, solving one or two problems a day on LeetCode. I am continuing to learn new techniques, and trying to target more specific areas that I feel I could gain more experience in.
Nearing my 100th problem, I was presented with a question, and after a minute or two I recognized that I was dealing with a graph problem that was really disguised as nested arrays or a list of lists. Twenty or thirty minutes later, I had written up some code with a Breadth First Search algorithm to solve the problem without any help from the discussion board.
At that point, I realized that I was getting better at recognizing what types of problems I am being presented with and how to best formulate a solution. That was something I struggled with over the first 50 problems.
Well, at the time of this writing, I am still due for another round of interviews, and I will continue to practice on LeetCode for that.
But, I'm not necessarily practicing just for FAANG interviews. I am practicing to learn. There are still algorithm techniques that I want to get better at and learn more about. Challenges really excite me, and I like to think about and try to solve hard problems, whether they are some random internet challenges or some work related challenge.
The more I learn about how to formulate algorithms using these fundamental data structures, the more confidence I get in my abilities, and the better I feel about going into an interview or facing any other challenge that I come across. Some of the problems that I have long thought about on my own, I am finally seeing solutions utilizing things like topological sorting and priority queues. Maybe one day I'll get around to turning my ideas into code using these new things I have learned and make something awesome.
A very influential person in my professional career likes to do a crossword puzzle every day to keep his mind and vocabulary sharp. I had never really had a daily activity like that up until now. I enjoy solving the LeetCode problems, and have been thinking that I'll just call that my daily activity to keep my mind sharp. After all, I am already almost to the end of the March Daily LeetCode Challenge.
So far, I've only earned about 850 LeetCoins. Quite a distance away from getting that 6000 LeetCoin LeetCode t-shirt. But, maybe one day you'll see wearing it!