Dynamic Programming
You're climbing a staircase of n steps. Each move you can climb 1 or 2 steps. How many distinct ways are there to reach the top?
Naive recursion re-derives the same subproblems over and over (ways to reach step 5 needs ways to reach step 3 multiple times through different branches), causing exponential blowup. This is fibonacci wearing a different costume: ways(n) = ways(n-1) + ways(n-2), because your last move to reach step n was either a 1-step from n-1 or a 2-step from n-2. Track just the last two results as you count upward, no recursion or array needed.
// You're climbing a staircase of n steps. Each move you can climb
// either 1 or 2 steps. How many distinct ways to reach the top?
// --- Brute force: recursion without caching, recomputes the same
// subproblems over and over — exponential blowup ---
function climbStairsBrute(n) {
if (n <= 2) return n;
return climbStairsBrute(n - 1) + climbStairsBrute(n - 2);
}
// --- Optimal: this is just fibonacci in disguise. Ways to reach step
// n = ways to reach (n-1) [then take 1 step] + ways to reach (n-2)
// [then take 2 steps]. Bottom-up with two rolling variables, O(1) space. ---
function climbStairs(n) {
if (n <= 2) return n;
let prev2 = 1; // ways to reach step 1
let prev1 = 2; // ways to reach step 2
for (let i = 3; i <= n; i++) {
const current = prev1 + prev2;
prev2 = prev1;
prev1 = current;
}
return prev1;
}
// --- Example Usage ---
console.log(climbStairs(2)); // 2 -> (1+1), (2)
console.log(climbStairs(3)); // 3 -> (1+1+1), (1+2), (2+1)
console.log(climbStairs(5)); // 8
console.log(climbStairsBrute(5)); // 8, same answer, much slower for large n