YP-DSA
The way I teach it
Preface
This is the book I wish I had when I started teaching CSS 342 and 343 at UW Bothell. It is not a comprehensive reference and it is not a polished textbook. It is the working notes of how I think about data structures, algorithms, and C++, written down so my students can read them between lectures.
If you are taking my class, you are in the right place. If you are not, you are still welcome — the material is general, the examples are LeetCode-flavored, and the code compiles.
0.1 What this book is
It is one continuous course in two parts:
- Part I (CSS 342) is the foundations course: C++ mechanics, STL containers, pointers, classes, the Rule of Three, templates, recursion, complexity analysis, sorting, induction, linked lists, and binary trees.
- Part II (CSS 343) picks up where 342 leaves off: balanced trees, heaps, graphs, hash tables, divide-and-conquer, greedy, dynamic programming, OOP design patterns, and a closing tour through computability and language theory.
Each chapter is one 120-minute lecture. Twenty per course. Forty in total.
0.2 How I teach, and what that means for this book
A few things you should expect, because they show up on every page.
Code first. I do not introduce a concept by defining it. I show you a problem, write the code, and we talk about what just happened. If you skim the prose, you can usually still pass an exam. If you skip the code, you cannot.
Warmups on the first slide. Every lecture opens with a LeetCode warmup. We solve it together. Sometimes it has nothing to do with that day’s topic. Sometimes it has everything to do with it and I will not tell you which until the end. Try the warmup before reading the chapter.
Debug lines stay in. When I write code in class I leave the cout statements that helped me debug it. Sometimes I comment them out, sometimes I leave them as is, but they do not get cleaned up. You will see them throughout. The mess is the point — that is what real coding looks like.
int binarySearch(const vector<int>& v, int target) {
int lo = 0;
int hi = v.size() - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
// cout << "lo: " << lo << ", hi: " << hi << ", mid: " << mid << endl;
if (v[mid] == target) return mid;
if (target < v[mid]) hi = mid - 1;
else lo = mid + 1;
}
return -1;
}That commented-out cout? It was there for a reason. You will see this pattern in every binary search in this book. Run it. Then comment it back out.
Helper before caller. When I decompose a problem I write the helper function first, then the function that calls it. The slides, the live coding, the textbook explanations — all bottom-up. If you see a function signature you do not recognize, scroll down. It is defined two paragraphs later.
The same problem, multiple ways. isPalindrome shows up for int, vector<int>, string, and ListNode* across different chapters. Same logical question, different containers. This is intentional. Algorithms are separable from the structures they run over, and the only way to feel that is to see it.
Growth mindset. You are going to be confused. That is the job. The students who get the most out of this course are not the ones who arrive understanding pointers — they are the ones who do not understand pointers in week 2, do not understand them in week 4, and then on week 6 something clicks. Stick with it.
0.3 What is “interactive” about an interactive book?
Each chapter has:
- A warmup with a link to the LeetCode problem and, where applicable, my own submission for comparison.
- Live code blocks that you can copy directly into a
.cppfile and compile. Every block in this book compiles withg++ -Wall -std=c++17. - Common-mistake callouts (red) — the things students consistently get wrong, with the bug visible.
- Pisan’s notes (green) — short asides where I tell you what I would say in lecture. Usually less than three sentences.
- Try-it boxes — small problems where you should stop reading and write code.
- Self-check quizzes at the end of each chapter — multiple choice, designed to catch the misconception you are most likely to be holding.
- Challenges — three to five LeetCode problems per chapter, in difficulty order.
The book is built with Quarto. Source markdown lives in book/ of the dsa-instructor repo. Pull requests welcome — especially fixes for things I got wrong, which there will be.
0.4 How to read this book
If you are taking the class, read the chapter corresponding to the upcoming lecture before class. Do the warmup. The 120 minutes of lecture will then be reinforcement and live coding, not first exposure.
If you are not taking the class, read in order. Each chapter assumes the previous ones. You can skip Lectures 11, 12, and 15 (the discrete math lectures) on a first pass if you only want the data structures and algorithms.
If you only have a weekend, read:
- Chapter 4 (Pointers and Memory)
- Chapter 7 (Copy Constructors and the Rule of Three)
- Chapter 9 (Recursion)
- Chapter 13 (Algorithm Analysis)
- Chapter 17 (Binary Trees Intro)
- Chapter 25 (Heaps)
- Chapter 33 (DP I)
That sequence will give you 70% of the value in 20% of the pages.
0.5 A note on the textbook
CSS 342 has historically used Data Abstraction and Problem Solving with C++ (Walls and Mirrors) by Carrano and Henry. That book is a good reference. This is not its replacement — this is the parallel track, the working notes, the thing my students kept asking me to write down. Read them together if you want both views.
0.6 Thanks
To every CSS 342 and CSS 343 student who pushed back when something was unclear, asked the question in Discord at 1 AM, or sent me a corrected solution that was better than mine. This book is mostly yours.
— Yusuf Pisan Woodinville, WA
I almost titled this book Walls and Pointers but my editor talked me out of it.