Phase 8 · Strings, Math & IntractabilityModule 36~34 min read

Coping with Hard Problems & Choosing an Algorithm

When a problem is intractable, you approximate. Plus a decision framework and master cheat sheet to pick the right algorithm.

What you'll learn

The final module is about judgment. When a problem is NP-hard, you don't give up — you approximate or use heuristics. And for any problem, you need a way to choose the right approach. We close with a decision framework and a master cheat sheet of everything you've learned.

By the end you'll be able to:

  • Use approximation algorithms with provable ratios
  • Apply heuristics and local search
  • Follow a framework to choose an algorithm for any problem

Approximation algorithms

An approximation algorithm runs in polynomial time and returns a solution provably close to optimal. Its approximation ratio bounds how far off it can be — a 2-approximation is never worse than twice optimal. The classic: cover every edge by greedily taking both endpoints of any uncovered edge — at most twice the minimum vertex cover:

Language
vertex_cover.py
def vertex_cover_2approx(edges):
    cover = set()
    for u, v in edges:
        if u not in cover and v not in cover:
            cover.add(u); cover.add(v)   # take BOTH endpoints
    return cover
# guaranteed at most 2x the optimal cover size

Note

Some problems approximate beautifully (metric TSP has a 1.5-approximation); others resist — for general TSP, even a constant-factor approximation is NP-hard. Knowing a problem's approximability is part of knowing the problem.

Heuristics & local search

A heuristic has no guarantee but works well in practice. Local search starts with a solution and repeatedly makes small improving changes until stuck at a local optimum. To escape local optima, simulated annealing sometimes accepts worse moves (less often over time), and genetic algorithms evolve a population of solutions. These power real-world scheduling, routing, and layout where optimal is out of reach.

Tip

For NP-hard problems on small inputs, exact methods still work: branch & bound (Module 22), bitmask DP (Module 20), or parameterized algorithms that are exponential only in a small parameter k, not in n.

A decision framework

Faced with any algorithmic problem, work through four steps:

Choosing an algorithm
1

Understand

Nail the inputs, outputs, constraints, and input size n.

2

Match a paradigm

Brute force, greedy, divide & conquer, DP, or a graph model?

3

Analyze

Work out the Big-O. Is it fast enough for the given n?

4

If intractable

Approximate, use heuristics, or restrict the input.

The input size is your compass: n ≤ 20 invites exponential methods (bitmask, backtracking); n ≤ 10⁴ tolerates O(n²); n ≤ 10⁶ wants O(n log n) or better; huge n demands near-linear or streaming algorithms.

The master cheat sheet

Every headline algorithm from the course, at a glance:

ProblemBest-known timeTechnique
Sort (comparison)O(n log n)Merge / heap / quick
Sort (integer)O(n + k)Counting / radix
Search (sorted)O(log n)Binary search
k-th smallestO(n) expectedQuickselect
Shortest path (≥0)O((V+E) log V)Dijkstra
Shortest path (any)O(V·E)Bellman-Ford
All-pairs pathsO(V³)Floyd-Warshall (DP)
Minimum spanning treeO(E log V)Kruskal / Prim (greedy)
Max flowO(V·E²)Edmonds-Karp
Bipartite matchingO(E√V)Hopcroft-Karp / flow
0/1 knapsackO(n·W)Dynamic programming
Edit distance / LCSO(n·m)Dynamic programming
String searchO(n + m)KMP / Z / Rabin-Karp
Primes ≤ nO(n log log n)Sieve of Eratosthenes
Convex hullO(n log n)Monotone chain
NP-hard (e.g. TSP)Exponential / approx.B&B, DP, approximation

Where to go next

You now hold the core algorithmic toolkit: analysis, the great paradigms, graph algorithms, and the theory of hardness. From here, deepen with advanced data structures (segment trees, Fenwick trees, link-cut trees — see our Data Structures course), competitive programming practice, or specialized fields like computational geometry, flows & matchings, and approximation theory. But the real skill isn't memorizing algorithms — it's recognizing which paradigm a new problem wants. That instinct is what this course was built to grow.

Recap & quick check

Key takeaways

  • Approximation algorithms run in polynomial time with a provable ratio (e.g. 2× optimal).
  • Heuristics and local search (annealing, genetic) trade guarantees for practical quality.
  • For NP-hard problems on small inputs, exact methods (B&B, bitmask DP, FPT) still work.
  • Choose an algorithm by input size: n≤20 exponential, ≤10⁴ quadratic, ≤10⁶ near-linear.
  • Master skill: recognize which paradigm a new problem calls for.

Quick check

1. What does a 2-approximation algorithm guarantee?

2. Why does simulated annealing sometimes accept worse moves?

3. For n ≤ 20, which approach becomes viable?

4. What's the single most valuable algorithmic skill?

That's the whole journey — from what an algorithm is to the frontier of what computers can do efficiently. Congratulations on completing The Complete Algorithms Course. Now go build something fast. 🚀