Aller au contenu principal
Data structures, algorithms, and the core CS foundations — plus an optional advanced track for expert topics.

Core Computer Science

Data structures, algorithms, and the core CS foundations — plus an optional advanced track for expert topics.

Divide and Conquer

Divide and Conquer (D&C) solves a problem in three steps:

  1. Divide — split the input into smaller, independent subproblems.
  2. Conquer — solve each subproblem recursively (base cases are trivial).
  3. Combine — merge the subproblem solutions into the full answer.

It is the engine behind the algorithms you already visualized in the sorting studio: Merge Sort (split, sort, merge), Quick Sort (partition, sort halves), and Binary Search (halve and recurse).

The Divide / Conquer / Combine Pattern

The pattern is only powerful when the split actually shrinks the work. Three properties make D&C pay off:

  • Subproblems are independent — each piece is solved in isolation, with no shared state and no repeated computation across branches.
  • The split is balanced — halving (or dividing by a constant b) keeps the recursion depth logarithmic.
  • Combining is cheap relative to n — Merge Sort’s merge is O(n); a combine that costs O(n²) can erase all the benefit of splitting.

Analyzing D&C with Recurrences

D&C algorithms have a natural recurrence:

T(n) = a · T(n/b) + f(n)
  • a subproblems, each of size n/b, plus f(n) cost to divide and combine.

The Master Theorem resolves these:

  • f(n) = O(n^c) with c < log_b(a) → T(n) = O(n^(log_b a))
  • f(n) = Θ(n^c) with c = log_b(a) → T(n) = O(n^c log n)
  • f(n) = Ω(n^c) with c > log_b(a) → T(n) = O(f(n))

The interesting case is the first: when splitting creates more subproblems than the divide shrinks them (a > b), the conquer side dominates and the exponent climbs — Strassen’s 7T(n/2) + O(n²) gives O(n^2.807).

D&C vs DP vs Greedy

The decisive question is what happens to the subproblems — independent, overlapping, or solvable by a single greedy choice:

Divide & ConquerDynamic ProgrammingGreedy
SubproblemsIndependentOverlappingSingle choice per step
Repeated workNonePlenty without a tableNone
Correctness driverRecurrence + combineMemoized recurrenceExchange/greedy proof
ExampleMerge Sort, KaratsubaKnapsack, LCSDijkstra, Huffman

D&C needs no table because each subproblem appears once. When the same subproblem recurs (Fibonacci recursion, LCS), you are really doing DP and should memoize. When an optimal next step exists and never needs revisiting, greedy skips recursion entirely.

Classic Examples

AlgorithmIdeaComplexity
Binary SearchHalve the search space per stepO(log n)
Merge SortSplit, sort halves, mergeO(n log n)
QuickselectPartition like quicksort, recurse into one sideO(n) average
Karatsuba3 multiplications of half size instead of 4O(n^1.585)
Closest PairSplit plane, recurse, check thin strip across the cutO(n log n)
FFTSplit polynomial into even/odd termsO(n log n)

Karatsuba is the template for the whole family: naive multiplication does 4 half-size multiplications (T(n) = 4T(n/2)); Karatsuba reuses the diagonal to do 3, dropping the exponent from log2 4 = 2 to log2 3 ≈ 1.585.

Worked Example

Merge Sort on [5, 2, 8, 1, 9, 3]:

          [5, 2, 8, 1, 9, 3]
         /                  \
   [5, 2, 8]              [1, 9, 3]
   /      \               /      \
 [5]  [2, 8]           [1]    [9, 3]
        /  \                  /   \
      [2]  [8]              [9]  [3]

Each merge compares only the heads of the two already-sorted halves, so every level costs O(n) and there are log n levels — O(n log n) total, with no comparison wasted.

When D&C Is the Wrong Tool

  • Overlapping subproblems — if the recursion recomputes the same state, you have DP and a memo table is mandatory (naive Fibonacci is O(2^n)).
  • Expensive combine — a merge that costs O(n²) makes T(n) = 2T(n/2) + n² reduce to O(n²): no gain over a direct algorithm.
  • A greedy choice already works — Dijkstra’s and Huffman’s are simpler than any D&C formulation.
  • Unbalanced splits — quicksort’s worst case (already-sorted input, bad pivot) degrades to O(n²).

Practice Trajectory

  1. Implement Merge Sort and Quick Sort by hand, then prove their recurrences with the Master Theorem.
  2. Move on to closest-pair and inversion counting (a Merge Sort variant), then to FFT and Strassen to see the “reduced subproblem count” trick that powers near-linear algorithms.
  3. Implement quickselect and confirm it finds the k-th smallest element in O(n) average time.
  4. Take a recursive Fibonacci you wrote earlier, classify it as DP (overlapping), and memoize it — then explain why the table is required.
  5. Work Karatsuba on two 4-digit numbers by hand and count multiplications against the naive method.

When It’s the Right Tool

SituationTakeaway
Independent subproblems with a cheap combineDivide and conquer
Recurring subproblems (Fibonacci, LCS)Memoize → dynamic programming
An optimal next step exists without recursionGreedy
Need the k-th element in near-linear timeQuickselect
Multiply or transform large data faster than baselineKaratsuba / FFT