Problem

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?

OR

There are n stairs, a person standing at the bottom wants to reach the top. The person can climb either 1 stair or 2 stairs at a time. Count the number of ways, the person can reach the top.

Examples

Example 1:

Input: n = 1
Output: 1
Explanation: There is only one way to climb 1 stair

Example 2:

Input: n = 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps

Example 3:

Input: n = 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step

Example 4:

Input: n = 4
Output: 5
Explanation: Here are the steps - (1, 1, 1, 1), (1, 1, 2), (2, 1, 1), (1, 2, 1), (2, 2).

Solution

Method 1 - Recursion

We can easily find recursive nature in above problem.

Lets take n = 2, then we have 2 ways - either take 1 step twice or 2 steps in one go.

For n = 3, we have 3 ways:

  • One Step at a time
  • Two-step then one step
  • One step then Two-step

For n = 4, we have 5 ways: (1, 1, 1, 1), (2, 2), (1, 1, 2), (2, 1, 1), (1, 2, 1)

Now, lets take n = 6, and try to get the algorithm.

So in the next step, we need to calculate the number of ways taken to raise 5 steps and 4 steps.

We can build full tree for the steps taken as below (not complete for clarity):

Complexity

  • ⏰ Time complexity: O(2^n)
  • 🧺 Space complexity: O(n)

Code

Java
int climbStairs(int n)  {
    if(n==1) return 1;
    if(n==2) return 2;
    return climbStairs(n-1)+climbStairs(n-2);
}

Method 2 - Top Down DP

Code

Java
public int climbStairs(int n) {
	return climbStairs(n, new int[n + 1]);
}
private int helper(int n, int[] cache) {
	if (n == 1) {
		cache[n] = 1;
		return 1;
	}

	if (n == 2) {
		cache[n] = 2;
		return 2;
	} else if (cache[n] != 0) {
		return cache[n];
	}

	cache[n] = helper(n - 1, cache) + helper(n - 2, cache);
	
	return cache[n];
}

Complexity

  • ⏰ Time complexity: O(n)
  • 🧺 Space complexity: O(n)

Method 3 - Bottom UP DP

Code

Java
public int climbStairs(int n) {
	int[] dp = new int[n+1];

	//base case
	dp[1] = 1;

	if (n >= 2) {
		dp[2] = 2;
	}

	for (int i = 3; i<= n; i++) {
		dp[i] = dp[i - 1] + dp[i - 2];
	}
	return dp[n];
}

Complexity

  • ⏰ Time complexity: O(n)
  • 🧺 Space complexity: O(n)

Method 4- Using Fibonacci Numbers

The number of ways to reach the n-th stair on a staircase depends on whether you can take one step at a time (from the (n-1)th stair) or two steps at a time (from the (n-2)th stair). We’ll represent this total number of ways to reach the n-th stair as ways(n).

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

This is actually formula for generating nth fibonacci number. But notice one thing that ways(n) is equal to fib(n+1), hence we can reuse fib(n) function.

ways(1) = fib(2) = 1
ways(2) = fib(3) = 2
ways(3) = fib(4) = 3

Code

Java
// Returns number of ways to reach s'th stair
public int climbStairs(int s) {
	return fib(s + 1);
}

Complexity

  • ⏰ Time complexity: O(n). (It can be optimized to work in O(Logn) time using matrix approach)
  • 🧺 Space complexity: O(n)