The main problem with me w.r.t DP problem is forgetting it if i don't

practice. So I decided to revisit all the DP problems i solved once again

just to refresh my memory.

So first Lets start with a simple one. Here we go!!!

Climbing stairs from Leetcode.Explanation : 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 manydistinct 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. 1 step + 1 step

2. 2 steps

Example 2:

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

So how can we solve this simple problem?

As usual we can solve this problem using recursion.

But the problem with recursion is it will have exponential time complexity.

In recursive way the following is the solution

```java

public int climbStairs(int n) {

if(n == 1) return 1;

if(n == 2) return 2;

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

}

```

The logic of the above is :

* If n is 1 then there is only one way to climb the stair.

* If n is 2 then there are two ways to climb the stair.

* If n is greater than 2 then the number of ways to climb the stair is

the sum of the number of ways to climb the stair when n-1 and n-2.

So we recursively call climbStairs(n-1) and climbStairs(n-2) and

`add them to get the result.`

What is the problem with this approach?

The problem with this approach is it has exponential time complexity.

For example if n = 5 then the number of ways to climb the stair is 8.

So the number of recursive calls will be 8.

If n = 6 then the number of ways to climb the stair is 13.

So the number of recursive calls will be 13.

if n=7 then the number of ways to climb the stair is 21.

So the number of recursive calls will be 21.

So the time complexity of this approach is O(2^n).

`Where n is the number of stairs. and 2 is the number of ways to `

`climb the stair.`

If we construct a recursion tree for n=5 it will look like below.

![](img_1.png)

Space complexity of this approach is O(n) where n is the number of stairs.

Or in other words the depth of the recursion tree is n.

So lets get into the basic dynamic programming approach.

```java

class Solution {

// A function that represents the answer to the problem for a given state

private int dp(int i) {

if (i <= 2) return i; // Base cases

return dp(i - 1) + dp(i - 2); // Recurrence relation

}

public int climbStairs(int n) {

return dp(n);

}

}

```

The above approach is a top-down approach. Means we are solving the problem

`from the top to the bottom. The time complexity of the above approach is `

O(2^n) and the space complexity is O(n).

So this is not really dynamic programming.

This is just a recursive approach. So lets get into the bottom-up approach.

```java

class Solution {

public int climbStairs(int n) {

if (n <= 2) return n; // Base cases

int[] dp = new int[n + 1]; // Create an array to store

` // the subproblems`

dp[1] = 1; // Base case

dp[2] = 2; // Base case

for (int i = 3; i <= n; i++) {

dp[i] = dp[i - 1] + dp[i - 2]; // The recurrence relation

}

return dp[n]; // The answer to the problem for n steps

}

}

```

The above approach is a bottom-up approach. Means we are solving the problem

`from the bottom to the top. Also the above approach is a tabulation approach. `

Means we are solving the problem using an array to store the subproblems.

The time complexity of the above approach is O(n) and the space

complexity is O(n). The flow goes like this :

* dp[1] = 1 // Base case Means if there is only one stair thenthere is only one way to climb the stair.

* dp[2] = 2 // Base case Means if there are two stairs thenthere are two ways to climb the stair.

from 3 to n we calculate the number of ways to climb the stairusing the following formula.

`* dp[i] = dp[i - 1] + dp[i - 2] // The recurrence relation`

* dp[n] // The answer to the problem for n steps

So if you look at the first example of recursive approach the number

of recursive calls for n=5 is 8. But if you look at the bottom-up

`approach the number of steps to calculate the number of ways to climb the `

stair for n=5 is 5. So the time complexity of the bottom-up approach is O(n)

`and the space complexity is O(n).`

So lets get into another problem. This is a Medium one.

And this is a classic one.

The problem is House Robber from Leetcode.You are a professional robber planning to rob houses along a street.

Each house has a certain amount of money stashed,

the only constraint stopping you from robbing each of them is thatadjacent houses have security systems connected and it will

automatically contact the police if two adjacent houses were broken into on

the same night.

Base case : If there is 4 houses then the maximum amount of money you

can rob is the maximum of the amount of money in the first house and

the amount of money in the second house. plus the maximum amount of

money you can rob from the remaining houses.

The intuition behind the problem is the following.maxRobbedAmount[0]=nums[0]

maxRobbedAmount[1]=max(maxRobbedAmount[0],nums[1])

maxRobbedAmount[2]=max(maxRobbedAmount[0]+nums[2],maxRobbedAmount[1])

maxRobbedAmount[3]=max(maxRobbedAmount[1]+nums[3],maxRobbedAmount[2])

maxRobbedAmount[4]=max(maxRobbedAmount[2]+nums[4],maxRobbedAmount[3])

Equation : maxRobbedAmount[i]=max(maxRobbedAmount[i-2]+nums[i],

maxRobbedAmount[i-1])

So the solution is the following.

```javaclass Solution {

public int rob(int[] nums) {

if (nums.length == 0) return 0;

if (nums.length == 1) return nums[0];

if (nums.length == 2) return Math.max(nums[0], nums[1]);

int[] maxRobbedAmount = new int[nums.length];

maxRobbedAmount[0] = nums[0];

maxRobbedAmount[1] = Math.max(nums[0], nums[1]);

for (int i = 2; i < nums.length; i++) {

maxRobbedAmount[i] = Math.max(maxRobbedAmount[i - 2] + nums[i],

maxRobbedAmount[i - 1]);

}

return maxRobbedAmount[nums.length - 1];

}

}

```The above approach is a bottom-up approach. Means we are solving the

problem from the bottom to the top. Also the above approach is a

tabulation approach. Means we are solving the problem using an array to

store the subproblems.So the time complexity of the above approach is O(n)

and the space complexity is O(n). Because we are using an array to store

the subproblems.