DSA

Climbing Stairs

4 approaches incl. A. Recursive, B. Memoized, B. Tabulation, and more. Optimal — Time O(n), Space O(1).

August 8, 2026

You are climbing a staircase. It takes n steps to reach the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Practice Link

Intuition#

The last move to reach step n is either a single step from n-1 or a double step from n-2 — there's no other way to land exactly on n. So the number of distinct ways to reach n is just the sum of the ways to reach n-1 and the ways to reach n-2:

ways(n) = ways(n-1) + ways(n-2)

That's the Fibonacci recurrence in disguise, with base cases ways(0) = 1 (one way to be already at the top — take zero steps) and ways(1) = 1 (one way — a single step).

The four implementations below all solve this same recurrence, just with increasingly better complexity:

  • Recursive: directly translates the recurrence into function calls. Correct, but recomputes the same subproblems exponentially many times — e.g. climbStairs(2) gets called 3 times while computing climbStairs(5).
  • Memoized: caches each climbStairsUtil(idx) result the first time it's computed, so every subproblem is solved exactly once — turns the exponential recursion into O(n).
  • Tabulation: builds the same values bottom-up in a dp array instead of top-down recursion, avoiding call-stack overhead entirely.
  • Tabulation, space optimized: since dp[i] only ever depends on the two preceding values, there's no need to keep the whole array — two rolling variables (prev1, prev2) suffice.

Implementation#

A. Recursive Approach#

cpp

class Solution {
public:
    int climbStairs(int n) {
        if(n==0)
            return 1;
        if(n<0)
            return 0;

        return climbStairs(n-1) + climbStairs(n-2);
    }
};

Time Complexity - O(2^n) -> TLE

Space Complexity - O(n)

B. Memoized Solution#

cpp
class Solution {
public:
    int climbStairsUtil(int idx, vector<int> &memo)
    {
        if(idx<0)
            return 0;
        if(idx==0)
            return 1;

        if(memo[idx] != -1)
            return memo[idx];

        return memo[idx] = climbStairsUtil(idx-1, memo) + climbStairsUtil(idx-2, memo);
    }

    int climbStairs(int n) {
        vector<int> memo(n+1, -1);

        return climbStairsUtil(n, memo);
    }
};

Time Complexity - O(n) -> overlapping cases handled via memoization

Space Complexity - O(n)

B. Tabulation Solution#

cpp
class Solution {
public:

    int climbStairs(int n) {
        if(n==0 || n==1)
            return 1;

        vector<int> dp(n+1);
        dp[0]=1;
        dp[1]=1;
        for(int i=2;i<=n;i++)
        {
            dp[i] = dp[i-1]+dp[i-2];
        }

        return dp[n];
    }
};

Time Complexity - O(n)

Space Complexity - O(n)

Tabulation : Space Optimized#

cpp
class Solution {
public:

    int climbStairs(int n) {
        if(n==0 || n==1)
            return 1;

        int prev2 = 1, prev1 = 1, curr;

        for(int i=2;i<=n;i++)
        {
            curr = prev1+prev2;
            prev2 = prev1;
            prev1 = curr;
        }

        return curr;
    }
};

Time Complexity - O(n)

Space Complexity - O(1)