Problem Statement:
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?
Example 1:
Input: n = 2
Output: 2
Explanation: There are two ways to climb to the top.
1 step + 1 step
2 steps
Example 2:
Input: n = 3
Output: 3
Explanation: There are three ways to climb to the top.
1 step + 1 step + 1 step
1 step + 2 steps
2 steps + 1 step
Constraints:
Solution:
1. Recursion and memoization:
class Solution {
public int climbStairs ( int n ) {
int [] dp = new int [n + 1 ];
//dp[i] represents the total ways to reach the i'th step.
Arrays. fill (dp, - 1 );
return climbStairsUtil (n, dp);
}
public int climbStairsUtil ( int n , int [] dp ) {
if (n == 1 || n == 2 || n == 0 ){
return n;
}
if (dp[n] != - 1 ){
return dp[n];
}
return dp[n] = climbStairsUtil (n - 1 , dp) + climbStairsUtil (n - 2 , dp);
}
}
2. Tabulation:
class Solution {
public int climbStairs ( int n ) {
int [] dp = new int [n + 1 ];
dp[ 0 ] = 0 ; //There're no ways to reach to 0th step from 0th step because we're already there.
dp[ 1 ] = 1 ;
for ( int i = 2 ; i <= n; i ++ ){
if (i == 2 ){
dp[i] = 1 + dp[i - 1 ];
}
if (i > 2 ){
dp[i] = dp[i - 1 ] + dp[i - 2 ];
}
}
return dp[n];
}
}
3. Space optimized:
class Solution {
public int climbStairs ( int n ) {
// Special cases for small values of n
if (n <= 1 ) {
return 1 ;
}
// Variables to store the number of ways to reach the previous step and the step before the previous step
int twoStepsBefore = 0 ;
int oneStepBefore = 1 ;
// Iterate from the second step to the nth step
for ( int step = 2 ; step <= n; step ++ ) {
int currentWays = 0 ;
if (step == 2 ) {
// Special case for the second step
currentWays = 1 + oneStepBefore;
} else {
// General case for steps greater than 2
currentWays = oneStepBefore + twoStepsBefore;
}
// Update the steps for the next iteration
twoStepsBefore = oneStepBefore;
oneStepBefore = currentWays;
}
return oneStepBefore;
}
}