Divide and conquer splits a problem into subproblems, solves them (often recursively), and combines their solutions. It shines when subproblems are similar and the combine step is efficient.
Master theorem for T(n) = a T(n/b) + f(n):
- Let n^{log_b a} be the critical term.
Case 1: if f(n) = O(n^{log_b a - ε}) → T(n) = Θ(n^{log_b a})
Case 2: if f(n) = Θ(n^{log_b a} log^k n) → T(n) = Θ(n^{log_b a} log^{k+1} n)
Case 3: if f(n) = Ω(n^{log_b a + ε}) and regularity holds → T(n) = Θ(f(n))
Use Akra–Bazzi for unbalanced splits or additive shifts, e.g., T(n) = T(n/2) + T(n/3) + n.
// Mergesort (stable)
function mergeSort(a) {
if (a.length <= 1) return a.slice();
const m = a.length >> 1;
const L = mergeSort(a.slice(0, m));
const R = mergeSort(a.slice(m));
const out = [];
let i = 0, j = 0;
while (i < L.length && j < R.length) {
if (L[i] <= R[j]) out.push(L[i++]); else out.push(R[j++]);
}
while (i < L.length) out.push(L[i++]);
while (j < R.length) out.push(R[j++]);
return out;
}