Subset sum equal to target
Problem Statement:β
We are given an array βARRβ with N positive integers. We need to find if there is a subset in βARRβ with a sum equal to K. If there is, return true else return false.
-
Example:
Solution: Memoizationβ
#include <bits/stdc++.h>
using namespace std;
bool f(int index, int target, vector<int> &arr, vector<vector<int>> &dp){
// Base Case: target becomes 0 => empty subset is valid
if(target == 0) return true;
// Only one element left
if(index == 0) return (arr[0] == target);
// Return if already computed
if(dp[index][target] != -1) return dp[index][target];
// Not pick the current element
bool notPick = f(index - 1, target, arr, dp);
// Pick the current element if it's not greater than target
bool pick = false;
if(arr[index] <= target)
pick = f(index - 1, target - arr[index], arr, dp);
return dp[index][target] = pick || notPick;
}
bool subsetSumToK(int n, int k, vector<int> &arr) {
vector<vector<int>> dp(n, vector<int>(k + 1, -1));
return f(n - 1, k, arr, dp);
}
Solution: Tabulationβ
#include <bits/stdc++.h>
using namespace std;
bool subsetSumToK(int n, int k, vector<int> &arr) {
vector<vector<bool>> dp(n, vector<bool>(k + 1, false));
// Fill base cases
for(int i = 0; i < n; i++)
dp[i][0] = true; // sum 0 is always possible
if(arr[0] <= k)
dp[0][arr[0]] = true;
// Fill DP table
for(int index = 1; index < n; index++){
for(int target = 1; target <= k; target++){
bool notPick = dp[index - 1][target];
bool pick = false;
if(arr[index] <= target)
pick = dp[index - 1][target - arr[index]];
dp[index][target] = pick || notPick;
}
}
return dp[n - 1][k];
}
Solution: Space Optimizedβ
#include <bits/stdc++.h>
using namespace std;
bool subsetSumToK(int n, int k, vector<int> &arr) {
vector<bool> prev(k + 1, false), curr(k + 1, false);
prev[0] = true;
if(arr[0] <= k) prev[arr[0]] = true;
for(int index = 1; index < n; index++){
curr[0] = true; // every row starts with target 0 as true
for(int target = 1; target <= k; target++){
bool notPick = prev[target];
bool pick = false;
if(arr[index] <= target)
pick = prev[target - arr[index]];
curr[target] = pick || notPick;
}
prev = curr;
}
return prev[k];
}
β How It Worksβ
- You're given an array of
nintegers and a target sumk. - You need to determine whether any subset of the array sums up to exactly
k. - At each index, you can either include or exclude the current element.
- Use Dynamic Programming to avoid recalculating overlapping subproblems.
π§© Key Formulaβ
dp[i][target] = dp[i-1][target] || dp[i-1][target - arr[i]]- Exclude: donβt pick the current element.
- Include: pick the current element if
arr[i] <= target.
β±οΈ Time & Space Complexityβ
| Approach | Time | Space |
|---|---|---|
| Recursion Only β | 2^n | O(n) stack |
| Memoization β | O(n*k) | O(n*k) |
| Tabulation β | O(n*k) | O(n*k) |
| Space Optimized β | O(n*k) | O(k) |
β οΈ Edge Casesβ
- Target
k = 0: Alwaystrue(empty subset). - Single element equal to
k: Should returntrue. - All elements greater than
k: Returnfalse. - Negative numbers not allowed (standard version).
π‘ Other Approachesβ
| Approach | Valid When |
|---|---|
| Recursion Only β | Just for understanding |
| Recursion + Memo β | Top-down with cache |
| Tabulation β | Bottom-up DP |
| Space Optimization β | Use only 1D array (rolling) |
π Related Problemsβ
- π‘ Partition Equal Subset Sum
- π‘ Count Subsets with Sum K
- π‘ Target Sum (LeetCode)
- π‘ Minimum Subset Sum Difference
- π‘ 0/1 Knapsack Problem
π¬