708220. Target Sum
Target Sum
Slug: target-sum-1626326450 Difficulty: Medium Id: 708220 Topic Tags: None Company Tags: None
Summary
The Target Sum problem is a classic dynamic programming problem that involves finding the total sum of subsets in an array. The goal is to find all combinations of elements in the array that add up to a given target sum. This problem requires understanding of dynamic programming, arrays, and recursion.
Detailed Explanation
To solve this problem, we can start by creating a 2D array dp where dp[i][j] represents whether there exists a subset with sum j using the first i elements of the array. We initialize all values in dp to false.
We then iterate through each element num in the array and for each num, we update the values in dp as follows:
- If
numis equal to the target sum, we setdp[i][j] = truefor alljfrom 0 totargetSum. - For each
jfromnumtotargetSum, ifdp[i-1][j-num] == true, we setdp[i][j] = true.
Finally, we iterate through the last row of dp and return all indices where dp[i][j] == true. These indices represent the combinations that add up to the target sum.
Here is a step-by-step breakdown:
1. Initialize dp[][] with false values
2. Iterate through each num in the array
3. For each num, update dp[][] as follows:
- If num = targetSum, set dp[i][j] = true for all j from 0 to targetSum
- For each j from num to targetSum, if dp[i-1][j-num] == true, set dp[i][j] = true
4. Iterate through the last row of dp[]
5. Return all indices where dp[i][j] == true
Time complexity: O(nw) where n is the size of the array and w is the target sum. Space complexity: O(nw)
Optimized Solutions
Java
public List<List<Integer>> findSubsets(int[] nums, int targetSum) {
boolean[][] dp = new boolean[nums.length][targetSum + 1];
for (int i = 0; i < nums.length; i++) {
for (int j = targetSum; j >= nums[i]; j--) {
if (j - nums[i] >= 0 && dp[i-1][j - nums[i]]) {
dp[i][j] = true;
} else if (nums[i] == targetSum) {
dp[i][j] = true;
}
}
}
List<List<Integer>> result = new ArrayList<>();
for (int j = 0; j <= targetSum; j++) {
if (dp[nums.length - 1][j]) {
List<Integer> subset = new ArrayList<>();
int sum = 0;
for (int i = nums.length - 1; i >= 0; i--) {
while (i > 0 && dp[i][sum + nums[i]] && sum + nums[i] <= targetSum) {
subset.add(nums[i]);
sum += nums[i];
i--;
}
if (sum == j) {
result.add(new ArrayList<>(subset));
break;
}
}
}
}
return result;
}