Why Some Problems Have No Known Efficient Algorithm
Every algorithm covered so far in this series — sorting, shortest paths, minimum spanning trees — runs in polynomial time, meaning its running time is bounded by some polynomial function of the input size. But a large and practically important class of problems has no known polynomial-time algorithm, despite decades of effort by researchers worldwide. This article explains the theory that classifies these problems and explains why their apparent difficulty is not simply a matter of insufficient cleverness.
The Complexity Class P
P is the class of decision problems (problems with a yes/no answer) solvable by a deterministic algorithm in polynomial time. Every algorithm discussed throughout this series — sorting in O(n log n), shortest paths in O(VE) or better, minimum spanning trees in O(E log V) — solves a problem in P. Problems in P are generally considered Tractable, meaning practically solvable even for large inputs.
The Complexity Class NP
NP stands for "Nondeterministic Polynomial time," but is more intuitively understood through the concept of Verification: a problem is in NP if, given a proposed solution (called a Certificate), that solution can be verified as correct in polynomial time, even if finding the solution in the first place might be much harder.
Example: the Hamiltonian cycle problem
(does a graph contain a cycle visiting every vertex exactly once?)
Finding such a cycle from scratch might require
checking an exponential number of possible orderings
But VERIFYING a proposed cycle is trivial:
just check that it visits every vertex exactly once
and that consecutive vertices in the proposed cycle
are actually connected by edges — this takes only O(V) timeSince P problems can obviously be verified in polynomial time (simply re-solve them from scratch, which is already fast), every problem in P is also in NP, giving the relationship P ⊆ NP. The famous open question, P vs. NP, asks whether this containment is strict — whether there exist problems in NP that are not in P, meaning verifiable quickly but not solvable quickly.
Reductions: Comparing Problem Difficulty
A Polynomial-Time Reduction from problem A to problem B is a polynomial-time algorithm that transforms any instance of A into an equivalent instance of B, such that the answer to the transformed instance of B is the same as the answer to the original instance of A.
If A reduces to B in polynomial time (written A ≤ₚ B),
this means: if B can be solved in polynomial time,
then A can also be solved in polynomial time
(simply reduce A to B, then solve B)
Equivalently: if A cannot be solved in polynomial time,
then B cannot be solved in polynomial time either
(otherwise A could be solved via the reduction)Reductions are the fundamental tool for comparing the relative difficulty of problems: a reduction from A to B shows that B is "at least as hard" as A, since any algorithm for B immediately yields an algorithm for A.
NP-Hardness and NP-Completeness
A problem H is NP-Hard if every problem in NP can be reduced to it in polynomial time — meaning H is at least as hard as every problem in NP. A problem is NP-Complete if it is both NP-hard and itself a member of NP.
NP-Complete problems are, informally, the "hardest"
problems in NP: if any single NP-complete problem
could be solved in polynomial time, then EVERY
problem in NP could also be solved in polynomial time,
proving P = NPThis is why NP-completeness is such a significant classification: it connects an individual problem's difficulty to the resolution of the entire P versus NP question, one of the most important open problems in all of computer science and mathematics.
The Cook-Levin Theorem: The First NP-Complete Problem
Establishing that any problem is NP-complete initially seems circular — how can a problem be shown at least as hard as "every problem in NP" without checking infinitely many problems individually? The breakthrough Cook-Levin Theorem resolved this by directly proving that SAT (the Boolean satisfiability problem: given a Boolean formula, does some assignment of true/false values to its variables make the whole formula true?) is NP-complete, using a direct construction based on the formal definition of a Turing machine.
Building the Web of NP-Complete Problems Through Reductions
Once one problem is known to be NP-complete, proving a new problem X is NP-complete no longer requires this fundamental construction. Instead, it only requires two steps.
To prove problem X is NP-complete:
Step 1: Show X is in NP
(a proposed solution to X can be verified in polynomial time)
Step 2: Show some known NP-complete problem Y
reduces to X in polynomial time (Y ≤ₚ X)
(this shows X is at least as hard as Y,