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: full engagement in lab activities; (2) Q-and-A with the TAs.
  • Outside class:
    • Narrative notes. Write carefully and thoughtfully.
    • Pen-and-paper problems. To get the most out of these, set aside quiet time, do NOT google/AI 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.
    • Quiz/exam prep. A good way to review is to read the module material first, then your narrative notes.
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.