[61B SP25] Lecture 37 - Algorithm Design and Reductions
[61B SP25] Lecture 37 - Algorithm Design and Reductions
We'll be running a Project 3 Showcase day Sunday, May 11, from 12:00-15:00 in
the Woz.
Show off your project 3 to other students! Or come by and see what creative ideas
were developed!
The facts.
● Treating alphabet size as constant, LSD Sort has runtime Θ(WN).
● Merge Sort has runtime between Θ(N log N) and Θ(WN log N).
The facts:
● Treating alphabet size as constant, LSD Sort has runtime Θ(WN).
● Merge Sort is between Θ(N log N) and Θ(WN log N).
AAAAAAAAAAAAA…….AB
Merge
LSD
Partition Counting
MSD
Insertion If insert into BST, equiv. to
Small-Alphabet (e.g. Integer) Sorting Algorithms:
Counting
Sorting vs. Searching
Merge
LSD
Partition Counting
MSD
Insertion If insert into BST, equiv. to
Small-Alphabet (e.g. Integer) Sorting Algorithms:
Counting
Going Even Further
Many of these ideas can be mixed and matched with others. Examples:
● What if we use quicksort as a subroutine for MSD radix sort instead of
counting sort?
● Implementing the comparable interface means an object can be stored in our
compareTo-based data structures (e.g. TreeSet), or sorted with our
comparison based sorts. Is there a single equivalent interface that would
allow storage in a trie AND radix sorting? What would that interface look like?
● If an object has both digits AND is comparable, could we somehow use an
LLRB to improve radix sort in some way?
Sounds of Sorting Algorithms
● Lists/Deques
○ Store a collection of items in order.
○ Adding/removing from end in constant (amortized) time
○ Getting/Setting in constant time
○ Sorting in N log N time (Quicksort, Mergesort, etc.)
● Disjoint Set
○ Store a graph
○ Can determine if two nodes are connected in α(N) time
● Set/Map
○ Store a collection of items with no order (or key-value pairs)
○ Adding/removing any item in constant (amortized) time
○ Getting/setting in constant (amortized) time
● Heap
○ Store a collection of items
○ Adding/removing the smallest in log(N) time
● Graph
○ Store a graph
○ Dijkstra's, A*, Prim's, Kruskal's, etc.
Problems we've solved
Algorithm Design and Asymptotic Analysis are the two most "creative" parts of 61B
● Large portion of CS theory
● First step when making a new algorithm (don't start coding until you have a plan!)
● Often tested in interviews
There's no easy "trick" to solving these; the easiest way to get better is through practice.
Fortunately, there are many programming challenge websites which you can use to practice.
● Leetcode, Codeforces: Similar to interview questions, harder ones veer into competitive
programming territory
● Advent of Code: Yearly code challenge that releases one problem per day in December
● Project Euler: More mathy than the others, less focused on runtime bounds
The rest of today will be algorithm design practice (goal is to describe an algorithm within a given
runtime bound)
For each problem, I'll include the approximate difficulty of coming up with the algorithm from
scratch (3/5 is around the difficulty of the hardest problems we'll ask on final exams). No specific
information/algorithm in this section is considered in scope.
Duplicate
You are given a list of N integers (unsorted). Determine if the list contains at least one pair of
duplicates
Example:
[1,2,3,10,5,8,10] -> True
[1,4,0,-5] -> False
Runtime Requirements:
O(N log N) : ★☆☆☆☆
O(N): ★★☆☆☆
Duplicate
You are given a list of N integers (unsorted). Determine if the list contains at least one pair of
duplicates
Example:
[1,2,3,10,5,8,10] -> True
[1,4,0,-5] -> False
Runtime Requirements:
O(N log N) : ★☆☆☆☆
Sort the list, then run dup2 from Lecture 15
O(N): ★★☆☆☆
Insert all integers into a set, then check if that set contains exactly N items
Source: 61B Final Exam, Summer 2024
You are given a graph whose edges are values between 0 and 1 (not inclusive), a start vertex, and
an end vertex. Find the path whose edges multiply to the largest value.
Example: 0.6 * 0.7 * 0.8 = 0.336, which is the largest possible value attainable in the below graph
Difficulty: ★★★☆☆
Source: 61B Final Exam, Summer 2024
You are given a graph whose edges are values between 0 and 1 (not inclusive), a start vertex, and
an end vertex. Find the path whose edges multiply to the largest value.
Example: 0.6 * 0.7 * 0.8 = 0.336, which is the largest possible value attainable in the below graph
Difficulty: ★★★☆☆
Solution 1: Run Dijkstra's algorithm, but multiply instead of adding the weights, and use a max heap
instead of a min heap. This works because the product of weights always decreases (you can't
take an edge and increase the product).
Source: 61B Final Exam, Summer 2024
You are given a graph whose edges are values between 0 and 1 (not inclusive), a start vertex, and
an end vertex. Find the path whose edges multiply to the largest value.
Example: 0.6 * 0.7 * 0.8 = 0.336, which is the largest possible value attainable in the below graph
Difficulty: ★★★☆☆
Solution 1: Run Dijkstra's algorithm, but multiply instead of adding the weights, and use a max heap
instead of a min heap. This works because the product of weights always decreases (you can't
take an edge and increase the product).
Solution 2: (★★★★☆) Create a new graph, but replace each edge of weight w with an edge of
weight -log_2(w) (this is guaranteed to be positive, since the edge weights are between 0 and 1.
Minimizing the sum of -log(x) - log(y) - log(z) -...
is the same as maximizing the sum of log(x) + log(y) + log(z) +...,
which is the same as maximizing log(xyz…),
which is the same as maximizing xyz…
So if we run Dijkstra's on the new graph, we'll get the correct path.
A Slight Modification
You are given a graph whose edges are values between 0 and 1 (not inclusive), a start vertex, and
an end vertex. Find the path whose edges add to the largest value without visiting any node more
than once.
Example: 0.6 + 0.7 + 0.8 = 0.21, which is the largest possible value attainable in the below graph
Difficulty: ★★★★★★★★★★★★★★★★★★★★★★★★★★★
A Slight Modification
You are given a graph whose edges are values between 0 and 1 (not inclusive), a start vertex, and
an end vertex. Find the path whose edges add to the largest value without visiting any node more
than once.
Example: 0.6 + 0.7 + 0.8 = 0.21, which is the largest possible value attainable in the below graph
Difficulty: ★★★★★★★★★★★★★★★★★★★★★★★★★★★
Currently no known solution in polynomial time (and if you do solve this in polynomial time, you
earn $1000000)
Just like in asymptotic analysis, it's often hard to determine the difference between an easy and a
hard problem.
Why do you earn $1,000,000 for solving this problem?
Reducing Hamilton Path
The Hamilton Path Problem is the problem of, given a graph, determining if there is a path that
goes through all vertices exactly once.
Problem X is the problem of, given a graph whose edges are values between 0 and 1 (not
inclusive), a start vertex, and an end vertex, finding the path whose edges add to the largest value
without visiting any node more than once.
Show that the Hamilton Path Problem reduces to Problem X; that is, if you find an efficient solution
to Problem X, then you have an efficient solution to the Hamilton Path Problem (★★★☆☆)
Reducing Hamilton Path
The Hamilton Path Problem is the problem of, given a graph, determining if there is a path that
goes through all vertices exactly once.
Problem X is the problem of, given a graph whose edges are values between 0 and 1 (not
inclusive), a start vertex, and an end vertex, finding the path whose edges add to the largest value
without visiting any node more than once.
Show that the Hamilton Path Problem reduces to Problem X; that is, if you find an efficient solution
to Problem X, then you have an efficient solution to the Hamilton Path Problem (★★★☆☆)
Create a new graph with the same topology as the original graph, but with edge weights 0.5. Add
two new "dummy" nodes S and T that are connected to all other nodes with weight 0.1 Run
Problem X on this new graph from S to T, and return True if the path returned has length
0.2+0.5x(|V|-1)
Beans and Plates