Skip to content

Commit

Permalink
Merge pull request #30 from atulgoel126/main-day-2
Browse files Browse the repository at this point in the history
Solved all questions scheduled for day2
  • Loading branch information
atulgoel126 authored Sep 2, 2024
2 parents ab72e38 + 43305d2 commit 39ad4a0
Show file tree
Hide file tree
Showing 13 changed files with 715 additions and 563 deletions.
12 changes: 6 additions & 6 deletions README-schedule.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ This schedule is designed to help me prepare for the Google SDE3 interview, cove

## Day 2: Dynamic Programming

1. **[House Robber (Medium)](https://leetcode.com/problems/house-robber/)** - Question #198
2. **[Coin Change (Medium)](https://leetcode.com/problems/coin-change/)** - Question #322
3. **[Longest Increasing Subsequence (Medium)](https://leetcode.com/problems/longest-increasing-subsequence/)** - Question #300
4. **[Partition Equal Subset Sum (Medium)](https://leetcode.com/problems/partition-equal-subset-sum/)** - Question #416
5. **[Target Sum (Medium)](https://leetcode.com/problems/target-sum/)** - Question #494
6. **[Maximum Product Subarray (Medium)](https://leetcode.com/problems/maximum-product-subarray/)** - Question #152
1. **[House Robber (Medium)](https://leetcode.com/problems/house-robber/)** - Question #198
2. **[Coin Change (Medium)](https://leetcode.com/problems/coin-change/)** - Question #322
3. **[Longest Increasing Subsequence (Medium)](https://leetcode.com/problems/longest-increasing-subsequence/)** - Question #300
4. **[Partition Equal Subset Sum (Medium)](https://leetcode.com/problems/partition-equal-subset-sum/)** - Question #416
5. **[Target Sum (Medium)](https://leetcode.com/problems/target-sum/)** - Question #494
6. **[Maximum Product Subarray (Medium)](https://leetcode.com/problems/maximum-product-subarray/)** - Question #152

---

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
package leetcode.dynamic_programming.q152;

import java.math.BigInteger;

public class MaximumProductSubarray {
public int maxProduct(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
if (nums.length == 1) {
return nums[0];
}
BigInteger minInt = BigInteger.ZERO;
BigInteger p = BigInteger.ONE;

for (int n: nums) {
p = p.multiply(BigInteger.valueOf(n));
minInt = minInt.max(p);
if (p.equals(BigInteger.ZERO)) {
p = BigInteger.ONE;
}
}
p = BigInteger.ONE;

for (int i = nums.length - 1; i >= 0; i--) {
p = p.multiply(BigInteger.valueOf(nums[i]));
minInt = minInt.max(p);
if (p.equals(BigInteger.ZERO)) {
p = BigInteger.ONE;
}
}
return minInt.intValue();
}
}
35 changes: 34 additions & 1 deletion src/main/java/leetcode/dynamic_programming/q198/HouseRobber.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,39 @@
package leetcode.dynamic_programming.q198;

import java.util.Arrays;

public class HouseRobber {

public int rob(int[] nums) {
return -1;
if (nums == null || nums.length == 0) {
return 0;
}
int[] cache = new int[nums.length + 3];
Arrays.fill(cache, -1);
int firstStart = helper(nums, 0, cache);
int secondStart = helper(nums, 1, cache);
return Math.max(firstStart, secondStart);
}

/**
* recursive helper function to calculate the max possible amount that can be robbed.
* breaks down the problem into smaller steps - each step only care about its past and whether it should skip one or two
* @param nums amount of money in each house
* @param index current index the function needs to consider
* @param cache store the computed value for memoization
* @return max possible money that can be robbed starting from @param index
*/
private int helper(int[] nums, int index, int[] cache) {
if (index > nums.length - 1) {
return 0;
}
if (cache[index] != -1) {
return cache[index];
}
int skipOne = helper(nums, index + 2, cache);
cache[index + 2] = skipOne;
int skipTwo = helper(nums, index + 3, cache);
cache[index + 3] = skipTwo;
return nums[index] + Math.max(skipOne, skipTwo);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
package leetcode.dynamic_programming.q300;

import java.util.Arrays;

public class LongestIncreasingSubsequence {
public int lengthOfLIS(int[] nums) {
return 0;
if (nums == null || nums.length == 0) {
return 0;
}
if (nums.length == 1) {
return 1;
}

int n = nums.length;
int[] dp = new int[n];
Arrays.fill(dp, 1); // Initialize dp array with 1s

int maxLength = 1;

for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++ ) {
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
maxLength = Math.max(maxLength, dp[i]);
}
return maxLength;
}
}
49 changes: 48 additions & 1 deletion src/main/java/leetcode/dynamic_programming/q322/CoinChange.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,53 @@
package leetcode.dynamic_programming.q322;

import java.util.Arrays;

public class CoinChange {

public int coinChange(int[] coins, int amount) {
return -1;
if (coins == null || coins.length == 0 || amount < 0) {
return -1;
}
if (amount == 0) {
return 0;
}

Arrays.sort(coins);
reverseArray(coins);

int[] dp = new int[amount + 1];
// Setting max value as default to be used a flag.
// Any unreachable amount will remain as MAX_VALUE
Arrays.fill(dp, amount + 1);

// dp[amount]
// cost for amount 0 is 0
dp[0] = 0;

// for (int i = 0; i < dp.length; i++) {
// for (int coin: coins) {
// if (coin <= i) {
// dp[i] = Math.min(dp[i], dp[i - coin] + 1);
// }
// }
// }

for (int coin: coins) {
for (int i = coin; i <= amount; i++) {
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}
return dp[amount] > amount ? -1 : dp[amount];
}

private void reverseArray(int[] arr) {
int left = 0, right = arr.length - 1;
while (left < right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
package leetcode.dynamic_programming.q416;

import java.util.Arrays;

public class PartitionEqualSubsetSum {
public boolean canPartition(int[] nums) {
return false;

int sum = Arrays.stream(nums).sum();
if (sum % 2 != 0) {
return false;
}

int target = sum / 2;

boolean[] dp = new boolean[target + 1];
dp[0] = true;

for (int num: nums) {
for (int i = target; i >= num; i--) {
dp[i] = dp[i] || dp[i - num];
}
}
return dp[target];
}
}
31 changes: 29 additions & 2 deletions src/main/java/leetcode/dynamic_programming/q494/TargetSum.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
package leetcode.dynamic_programming.q494;

import java.util.HashMap;
import java.util.Map;

public class TargetSum {
public short findTargetSumWays(int[] nums, int target) {
return -1;
Map<String, Integer> memo = new HashMap<>();

public int findTargetSumWays(int[] nums, int target) {
return helper(nums, 0, 0, target);
}

private int helper(int[] nums, int index, int result, int target) {
if (index == nums.length) {
return result == target ? 1 : 0;
}
String key = index + "," + result;

if (memo.containsKey(key)) {
return memo.get(key);
}

int firstResult = result + nums[index];
int secondResult = result - nums[index];
int first = helper(nums, index + 1, firstResult, target);
int second = helper(nums, index + 1, secondResult, target);

int sum = first + second;
memo.put(key, sum);

return sum;
}
}
Original file line number Diff line number Diff line change
@@ -1,55 +1,78 @@
//1. Test for empty array:
//Input: []
//Expected Output: 0
//
//2. Test for array with only one element:
//Input: [10]
//Expected Output: 10
//
//3. Test for array with all positive integers:
//Input: [2, 3, 4, 5]
//Expected Output: 120 (product of all elements)
//
//4. Test for array with all negative integers:
//Input: [-2, -3, -4]
//Expected Output: -24 (product of all elements)
//
//5. Test for array with both positive and negative integers:
//Input: [2, -3, 4, -5]
//Expected Output: 60 (maximum product subarray is [4, -5])
//
//6. Test for array with multiple maximum product subarrays:
//Input: [2, -3, 4, -5, 1, 2]
//Expected Output: 60 (maximum product subarray is [4, -5])
//
//7. Test for array with zero:
//Input: [2, 0, -3, 1]
//Expected Output: 2 (maximum product subarray is [2])
//
//8. Test for array with multiple zeros:
//Input: [0, 1, 2, 0, 3]
//Expected Output: 2 (maximum product subarray is [2])
//
//9. Test for array with only zeros:
//Input: [0, 0, 0]
//Expected Output: 0
//
//10. Test for array with large and small integers:
//Input: [100, -2, -3, 4, 5]
//Expected Output: 300 (maximum product subarray is [100, -2, -3])
//
//11. Test for array with extremely large integers:
//Input: [23423423423, -3, 4345345]
//Expected Output: 23423423423 (maximum product subarray is [23423423423])
//
//12. Test for array with null values:
//Input: [2, null, -3, 0, 5]
//Expected Output: 10 (maximum product subarray is [2])
//
//13. Test for array with mixture of integers and non-numeric values:
//Input: [2, "hello", -3, 6, "world"]
//Expected Output: 36 (maximum product subarray is [2, "world"])
//
//14. Test for array with repeating values:
//Input: [2, 3, 3, 2]
//Expected Output: 9 (maximum product subarray is [3, 3])
package leetcode.dynamic_programming.q152;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class MaximumProductSubarrayTests {
private MaximumProductSubarray ob = new MaximumProductSubarray();

@Test
public void testBasicPositive() {
int[] nums = {2, 3, -2, 4};
assertEquals(6, ob.maxProduct(nums));
}

@Test
public void testAllNegative() {
int[] nums = {-2, -3, -4};
assertEquals(12, ob.maxProduct(nums));
}

@Test
public void testMixedWithZero() {
int[] nums = {-2, 0, -1};
assertEquals(0, ob.maxProduct(nums));
}

@Test
public void testSingleNumber() {
int[] nums = {4};
assertEquals(4, ob.maxProduct(nums));
}

@Test
public void testEmptyArray() {
int[] nums = {};
assertEquals(0, ob.maxProduct(nums));
}

@Test
public void testLargeNumbers() {
int[] nums = {1000, 1000, -2000, 1000};
assertEquals(1000000, ob.maxProduct(nums));
}

@Test
public void testAlternatingSignsWithZero() {
int[] nums = {-2, 3, -4, 5, -6, 0, 7, -8};
assertEquals(360, ob.maxProduct(nums));
}

@Test
public void testAllZeros() {
int[] nums = {0, 0, 0, 0, 0};
assertEquals(0, ob.maxProduct(nums));
}

@Test
public void testLargeArray() {
int[] nums = new int[1000];
for (int i = 0; i < nums.length; i++) {
nums[i] = (i % 2 == 0) ? 2 : 3;
}
assertEquals(0, ob.maxProduct(nums));
}

@Test
public void testWithOneNegativeNumber() {
int[] nums = {2, 3, -2, 4, 5};
assertEquals(20, ob.maxProduct(nums));
}

@Test
public void testOverflow() {
int[] nums = {0,10,10,10,10,10,10,10,10,10,-10,10,10,10,10,10,10,10,10,10,0};
assertEquals(1000000000, ob.maxProduct(nums)); // Result would be larger than Integer.MAX_VALUE
}
}
Loading

0 comments on commit 39ad4a0

Please sign in to comment.