Skip to content

Commit 52dbf36

Browse files
committed
Update dynamic programming problems and lodash utilities
1 parent ac4bba5 commit 52dbf36

File tree

66 files changed

+1194
-270
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1194
-270
lines changed

README.md

+20-30
Large diffs are not rendered by default.

src/java1/algorithms/dynamicProgramming/CoinsChange.java

-24
This file was deleted.

src/java1/algorithms/dynamicProgramming/LongestCommonSubsequence.java

-25
This file was deleted.

src/java1/algorithms/dynamicProgramming/LongestIncreasingSequence.java

-26
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package java1.algorithms.dynamicProgramming.coinsChange;
2+
import java.util.*;
3+
4+
public class CoinsChange {
5+
// TC: O(amount * numberOfCoins) SC: O(amount)
6+
private static int coinsChange(int[] coins, int amount) {
7+
int[] dp = new int[amount+1];
8+
Arrays.fill(dp, amount+1);
9+
dp[0] = 0;
10+
11+
for(int i=1; i<=amount; i++) {
12+
for(int coin: coins) {
13+
if(i-coin >=0) {
14+
dp[i] = Math.min(dp[i], 1 + dp[i-coin]);
15+
}
16+
}
17+
}
18+
return dp[amount] == amount +1 ? -1 : dp[amount];
19+
}
20+
21+
public static void main(String[] args) {
22+
int[] coins1 = {1, 3, 4, 5};
23+
int amount1 = 7;
24+
int[] coins2 = {2, 4};
25+
int amount2 = 3;
26+
System.out.println(coinsChange(coins1, amount1));
27+
System.out.println(coinsChange(coins2, amount2));
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
**Description:**
2+
Given an array of coins(`coins`) that contains different coin denominations and an integer amount(`amount`) which represents the total amount of money you want to make with these coins. Calculate the minimum number of coins needed to make up the given amount. If it is not possible to made up the amount, return -1.
3+
4+
**Note:** There is no limit on number of times each coin to be used.
5+
6+
## Examples:
7+
Example 1:
8+
9+
Input: coins = [1, 3, 4, 5], amount = 7
10+
Output: 2
11+
12+
Example 2:
13+
14+
Input: coins = [2, 4], amount = 3
15+
Output: -1
16+
17+
**Algorithmic Steps(Approach 1&2)**
18+
This problem is solved efficiently using **dynamic programming** approach by avoiding the recomputations of same subproblems. The algorithmic approach can be summarized as follows:
19+
20+
1. Initialize an array to hold the number of minimum coins for each amount value from `0` to given `amount`. By default, each value is assigned with out of bound value `amount+1`.
21+
22+
2. Since the amount `0` requires `0` coins, let's re-initialize the first value(`dp[0]=0`) with 0.
23+
24+
3. Iterate each amount value starting from `1` to `amount` to find the minimum coins required.
25+
26+
4. Iterate over each coin to make up the amount value.
27+
28+
5. If the difference between amount and coin value is greater than or equal to zero, the number of minimum coins is calculated by the minimum value of initial value(`dp[i]`) and remaining amount's coins incremented by 1(`1+dp[i-coin]`).
29+
30+
6. Repeat step 5 until all the icons verified.
31+
32+
7. Repeat steps 4-5 until the number of minimum coins calculated for each amount value.
33+
34+
8. Return `dp[amount]` which indicates the number of minimum coins required for give amount.
35+
36+
37+
**Time and Space complexity:**
38+
This algorithm has a time complexity of `O(amount * coins)`, where `amount` is the number of amount values from `1` to given input `amount` and `coins` indicates number of given coins. This is because we are traversing all the amount values with a list of coins.
39+
40+
Here, we will use array datastructure to store the minimum coins count for each amount value. Hence, the space complexity will be `O(amount)`.

src/java1/algorithms/dynamicProgramming/CombinationSum4.java renamed to src/java1/algorithms/dynamicProgramming/combinationSum4/CombinationSum4.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// TC: O(nums * target) SC: O(target)
2-
package java1.algorithms.dynamicProgramming;
2+
package java1.algorithms.dynamicProgramming.combinationSum4;
33

44
public class CombinationSum4 {
55
private static int combinationSum4(int[] nums, int target) {
@@ -16,8 +16,9 @@ private static int combinationSum4(int[] nums, int target) {
1616
}
1717

1818
public static void main(String[] args) {
19-
int[] nums = {1, 2, 3};
20-
int target = 4;
21-
System.out.println(combinationSum4(nums, target));
19+
int[] nums1 = {1, 2, 4}, nums2 = {7};
20+
int target1 = 5, target2 = 6;
21+
System.out.println(combinationSum4(nums1, target1));
22+
System.out.println(combinationSum4(nums2, target2));
2223
}
2324
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
**Description:**
2+
Given an array of unique integers `nums` and a target integer `target`, find out the number of possible combinations that add up to given target.
3+
4+
**Note:** Same element from `nums` can be used multiple times if required. Also, the different elements order considered as a different combination.
5+
6+
## Examples:
7+
Example 1:
8+
9+
Input: nums1 = [1, 2, 4], target1 = 5
10+
Output: 10
11+
12+
Example 2:
13+
14+
Input: nums2 = [7], target2 = 6
15+
Output: 0
16+
17+
**Algorithmic Steps(Approach 1&2)**
18+
This problem is solved efficiently using **bottom-up dynamic programming** approach by avoiding the recomputations of same subproblems. The algorithmic approach can be summarized as follows:
19+
20+
1. Create an array(`dp`) with the size of `length+1` and initialized all values to zero. This array is used to store the number of combinations that sum up to each value from `0` up to `target`.
21+
22+
2. The first value(`dp[0]=1`) is set to 1 since there will be only one possible combination(not using any elements) results in a sum of zero.
23+
24+
3. Iterate over all possible sub-targets(`i`) starting from `1` to `target` to find the combinations.
25+
26+
4. For each sub-target value `i`, iterate through all numbers of given array.
27+
28+
5. If the number(`num`) is less than or equal to current sub-target(`i`), then update the possible combinations by adding the previous combinations.
29+
30+
6. Repeat steps 4-5 until the target value is reached.
31+
32+
7. Return the number of combinations from the last element of an array(i.e, `dp[target]`)
33+
34+
35+
**Time and Space complexity:**
36+
This algorithm has a time complexity of `O(target * n)`, where `n` is the number of elements in `nums` and `target` is the number for which combinations needs to be calculated. This is because we need to traverse each sub-target and find the possible comnitions for each element of given array.
37+
38+
Here, we will use an array datastructure to store possible combinations for each sub-target. Hence, the space complexity will be `O(target)`.
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
package java1.algorithms.dynamicProgramming;
1+
package java1.algorithms.dynamicProgramming.houseRobber;
22

33
public class HouseRobber {
44
// TC:O(n) SC:O(1)
55
private static int robber1(int[] nums) {
6-
int rob1 = nums[0], rob2 = Math.max(rob1, nums[1]);
7-
for(int i=2; i< nums.length; i++) {
8-
int temp = Math.max(nums[i]+rob1, rob2);
6+
int rob1 = 0, rob2 = 0;
7+
for(int num: nums) {
8+
int newRob = Math.max(num+rob1, rob2);
99
rob1 = rob2;
10-
rob2 = temp;
10+
rob2 = newRob;
1111
}
1212
return rob2;
1313
}
@@ -16,16 +16,20 @@ private static int robber1(int[] nums) {
1616
private static int robber2(int[] nums) {
1717
int[] dp = new int[nums.length];
1818
dp[0] = nums[0];
19-
dp[1] = nums[1];
19+
dp[1] = Math.max(nums[0], nums[1]);
2020
for(int i=2; i<nums.length; i++) {
2121
dp[i] = Math.max(nums[i] + dp[i-2], dp[i-1]);
2222
}
2323
return dp[nums.length-1];
2424
}
2525

2626
public static void main(String[] args) {
27-
int[] nums = {2,7,9,3,1};
28-
System.out.println(robber1(nums));
29-
System.out.println(robber2(nums));
27+
int[] nums1 = {1, 5, 7, 2, 4};
28+
int[] nums2 = {8, 1, 2, 9};
29+
System.out.println(robber1(nums1));
30+
System.out.println(robber2(nums1));
31+
32+
System.out.println(robber1(nums2));
33+
System.out.println(robber2(nums2));
3034
}
3135
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
**Description:**
2+
Given an integer array `nums` where `nums[i]` represents the amount of money in the `ith` house. Calculate the maximum amount of money you can rob from the houses. Remember that you cannot rob two adjacent houses because the security system will automatically alert the police if two adjacent houses were broken into on the same night.
3+
4+
## Examples:
5+
Example 1:
6+
7+
Input: nums1 = [1,5,7,2,4]
8+
Output: 12
9+
10+
Example 2:
11+
12+
Input: nums2 = [8, 1, 2, 9]
13+
Output: 17
14+
15+
**Algorithmic Steps(Approach 1&2)**
16+
This problem is solved efficiently using **Fibonacci pattern bottom-up dynamic programming** approach by avoiding the recomputations of same subproblems. The algorithmic approach can be summarized as follows:
17+
18+
1. Initialize first(`rob1`) and second(`rob2`) houses money with zero.
19+
20+
2. Iterate over all the houses and get the money at each `i`th house.
21+
22+
3. Find the maximum possible money which can be robbed at each house. This is calculated by taking the maximum between sum of current house with second previous house and previous house money. This maximum money can be stored in a temporary varaible(`newRob`).
23+
24+
4. Move `rob1` pointing to next house(`rob2`). i.e, `rob1 = rob2`.
25+
26+
5. Update `rob2` pointing to current house(`newRob`) where the maximum possible money which can robbed at night is stored.
27+
28+
6. Repeat steps 3-5 until all the houses visited.
29+
30+
7. Return `rob2` which contains the maximum possible money which you can rob in the sequence of houses
31+
32+
33+
**Time and Space complexity:**
34+
This algorithm has a time complexity of `O(n)`, where `n` is the number of houses with money stashed. This is because we need to traverse over each house to find the maximum money.
35+
36+
Here, we are not using any additonal datastructure other than two variables to store money. Hence, the space complexity will be `O(1)`.
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
//TC: O(2n) ~O(n), SC:O(1)
2-
package java1.algorithms.dynamicProgramming;
2+
package java1.algorithms.dynamicProgramming.houseRobber2;
33

44
public class HouseRobber2 {
55
private static int rob(int[] nums) {
66
if(nums.length == 0) return 0;
77
if(nums.length == 1) return nums[0];
8-
if(nums.length == 2) return Math.max(nums[0], nums[1]);
98

109
return Math.max(robHelper(nums, 1, nums.length-1), robHelper(nums, 0, nums.length-2));
1110
}
1211

1312
private static int robHelper(int[] nums, int start, int end) {
14-
int rob1 = nums[start], rob2 = nums[start+1];
13+
int rob1 = 0, rob2 = 0;
1514

16-
for(int i = 2; i< nums[end]; i++) {
17-
int temp = Math.max(nums[i]+rob1, rob2);
15+
for(int i = start; i<= end; i++) {
16+
int newRob = Math.max(nums[i]+rob1, rob2);
1817
rob1 = rob2;
19-
rob2 = temp;
18+
rob2 = newRob;
2019
}
2120
return rob2;
2221
}
2322

2423
public static void main(String[] args) {
25-
int[] nums = {1, 2, 3, 1};
26-
System.out.println(rob(nums));
24+
int[] nums1 = {1, 5, 7, 2, 4}, nums2 = {1, 2, 3}, nums3 = {3};
25+
System.out.println(rob(nums1));
26+
System.out.println(rob(nums2));
27+
System.out.println(rob(nums3));
2728
}
2829
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
**Description:**
2+
Given an integer array `nums` where `nums[i]` represents the amount of money in the `i`th house. Calculate the maximum amount of money you can rob from the houses which are arranged in a circle. Remember that you cannot rob two adjacent houses(including the first and last house) because the security system will automatically alert the police if two adjacent houses were broken into on the same night.
3+
4+
## Examples:
5+
Example 1:
6+
7+
Input: nums1 = [1,5,7,2,4]
8+
Output: 11
9+
10+
Example 2:
11+
12+
Input: nums2 = [1, 2, 3]
13+
Output: 3
14+
15+
**Algorithmic Steps(Approach 1&2)**
16+
This problem is solved efficiently using **Fibonacci pattern bottom-up dynamic programming** approach by avoiding the recomputations of same subproblems. The algorithmic approach can be summarized as follows:
17+
18+
1. Accepts `nums` as input array which indicates the amount of money of each house.
19+
20+
2. Add base case conditions for zero and one houses. If there are no houses(`nums.length === 0`), the maximum money can get is zero. In case there is only one house(`nums.length === 1`), return that money as maximum amount.
21+
22+
3. Since the houses are arranged in a circle, the maximum money stolen from houses needs to be calculated for two sub-arrays(i.e, first subarray from first to last before house and second subarray from second to last house)
23+
24+
4. Create a helper function which accepts subarray as input to calculate the maximum amount can be robbed.
25+
26+
5. Start the helper function by initializing first(`rob1`) and second(`rob2`) houses money with zero.
27+
28+
6. Iterate over all the houses and get the money at each `i`th house.
29+
30+
7. Find the maximum possible money which can be robbed at each house. This is calculated by taking the maximum between sum of current house with second previous house and previous house money. This maximum money can be stored in a temporary varaible(`newRob`).
31+
32+
8. Move `rob1` pointing to next house(`rob2`). i.e, `rob1 = rob2`.
33+
34+
9. Update `rob2` pointing to current house(`newRob`) where the maximum possible money which can robbed at night is stored.
35+
36+
10. Repeat steps 3-5 until all the houses visited.
37+
38+
11. Return `rob2` which contains the maximum possible money which you can rob in the sequence of houses
39+
40+
12. Return the maximum money by invoking the helper function for subarrays mentioned in step3.
41+
42+
**Time and Space complexity:**
43+
This algorithm has a time complexity of `O(n)`(i.e, `O(2n) ~ O(n)`), where `n` is the number of houses with money stashed. This is because we need to traverse over two subarray sequence of houses to find the maximum money.
44+
45+
Here, we are not using any additonal datastructure other than two variables to store money. Hence, the space complexity will be `O(1)`.

0 commit comments

Comments
 (0)