Three Pieces of Advice for Learning Algorithms for the First Time
I just completed my first programming assignment for my Algorithms course through Coursera - if you're looking to continue or supplement your education, I highly recommend Coursera, I've been impressed with the quality of content and breadth of their course offerings.
Anyway, here are three pieces of advice if you're trying to learn algorithms for the first time like me.
1. Take a minute to stop and think
I know this sounds dumb and obvious, but since I've been out of a school setting for about four years, I'm used to just doing instead of taking a step back and deliberately planning out my next steps. Half the battle in solving a problem with algorithms is understanding the question. If you read a question and immediately race to your text editor to code up a solution, chances are, you don't fully grasp the question. More often than not, this leads to seemingly endless hours down a rabbit hole and trying to brute force your way to solve a problem. These sorts of technical questions usually have nuances to them and these nuances are hints to solving the question. If you miss those hints, you're headed down the wrong path.
2. Don't code, talk and write
Once you understand the problem, talk it out. Talking out the problem helps me be very explicit about my approach. If I start talking out my steps and get to a point where I can't even explain where to go myself, then I know I've reached a dead end. Also, if you can, talk to another person, if someone isn't available, talk to yourself. I've found that when I think to myself, I make connections or assumptions that glaze over details.
When I was first trying to implement the merge sort algorithm, I had a little trouble wrapping my head around recursion. I went to my roommate, Moses, and he was gracious enough to talk it out with me for about half an hour. We stepped through the call stack, wrote out examples and talked out different ways to view the algorithm. This was a huge help. I then wrote pseudo code of what we discussed and this helped cement what I had just learned.
A good test to figure out if you actually understand something is if you can explain it out loud or write it down on a piece of paper. So before you start coding a solution, talk it out and write some pseudo code. You'll know if you have the solution if you can do these two things. Writing the code is the last step, the hard work of actually solving the problem is already done.
When you actually get to coding the solution, check yourself that you don't get to the point where you're plugging and chugging, haphazardly coding in hopes of stumbling upon the solution. In the best case scenario, you'll use your pseudo code and it will flawlessly transfer to actual code, but this rarely happens, if ever. You'll run into snags. When you do, repeat steps one and two. Take a step back, talk and write it out. This will save time in the long run, trust me.
I fell victim of plugging and chugging when I was solving the inversion count problem (the first programming question of Coursera's Algorithm class). I knew I had 95% of the problem figured out, but for some reason my counter was always wrong at the very last level of recursion. I printed out the counts at each iteration and everything was as expected except for the very last. Seeing the finish line, I just tried to change a few things here and there in hopes of figuring it out, I was programming by coincidence. I lost hours to this futile approach. I thought I'd be able to quickly figure it out by trying a few random pieces of logic here and there instead of taking a minute and deliberately thinking about the problem. It wasn't until I stepped away from the code and talked out potential reasons why the counter screwed up at the last minute that I figured out what was wrong.
What was wrong? One line of code. On an edge case, I mistakenly added to the counter items I had already accounted for. Once I deleted that line, my code solved the problem.
Interestingly enough, these three thoughts all apply to programming in general. When I first started to learn how to program, I thought it was all about writing code. Yes, that's a big part of it, but code itself is a tool. Programming and computer science is more about a way of thinking and an to approach to solving a problem. I'd argue that real programming is the process leading up to actually writing a line of code.