CS 3212: Algorithms

How learning works in this course


Let's start by understanding why this course is important and what you'll take away from the course:

  • The main goal is to learn algorithmic thinking, a problem-solving technique unique to computer science.

  • What exactly is algorithmic thinking?
    • It is partly the ability to abstract away the unneeded details of a messy real-world problem, and get at the core algorithmic part so that an efficient algorithm can be devised.
    • It includes a strong working knowledge of key data structures, and classic algorithms (so that we know when to apply them, or modify them).
    • It is the ability to understand how an algorithm scales as the input data grows in size, and how to make choices to have the algorithm scale as well as possible.
    • It also includes a recognition of when something is truly difficult (and must be solved approximately) or requires deference to an expert or technical literature.

  • Why is algorithmic thinking important?
    • In the very short term, algorithmic thinking is needed to succeed in job interviews.
    • But short term aside, algorithmic thinking is a key factor in what separates a computer science major from someone who has merely learned programming. You get to be a decision maker, a technically trusted team member.
    • Long after you've gone past entry-level, your algorithmic thinking skills will play a role in high-level system design.
    • You certainly need algorithmic thinking for advanced CS, in grad school or outside.
    • Algorithmic problem-solving ability translates into problems-solving in other domains such as law or business.
    • Best reason: it's fun and intellectually exciting.

If the development of this skill were a matter of describing it, we would simply deliver a single lecture on the topic. Alas, it's a skill and, like any other skill acquisition, takes repeated practice.

Here's the thing about practicing (to learn any skill): it has be done with a good faith effort and strong motivation. (Can you imagine learning to play the piano half-heartedly, stabbing at the keys with minimal interest?) This type of sustained, high-focus effort is hard when life is busy with a million deadlines.

Let's look at how you will learn in the course:

  • Prior to class: a quick review of material from the last class, and doing the first couple of in-module exercises from the next module.
  • In class: (1) the module material; (2) giving your full effort to the exercises in class.
  • In lab: (1) demonstrate your completion of module exercises; (2) Q-and-A with the TAs.
  • Outside class:
    • Pen-and-paper problems. To get the most out of these, set aside quiet time, do NOT google them, and ideally struggle with them. It's that struggle that builds algorithmic thinking. (You won't develop the skill if you see the solution.)
    • Programming problems. Because these are intricate, work on them first with planning and pseudocode, and then in steps, always with a few examples, and always with pro-active debugging (lots of println's).
    • Module review. Read through a second/third time, working through an example by hand, perhaps in your team.
    • Complete remaining module (in-class) exercises. Do this with your review, each week.
The most important thing to remember is: you learn when you struggle with an algorithmic puzzle or exercise. The learning is much diminished if you are given the solution before you think for yourself - it's this very thinking-for-yourself we want to develop in the course.