Given an array arr of n integers and an integer target, determine if there is a subset of the given array with a sum equal to the given target.
Input: arr = [1, 2, 7, 3], target = 6
Output: True
Explanation: There is a subset (1, 2, 3) with sum 6.
Input: arr = [2, 3, 5], target = 6
Output: False
Explanation: There is no subset with sum 6.
Input: arr = [7, 54, 4, 12, 15, 5], target = 9
The idea is to generate all pssible subsets and whenever a single subsets is found whose sum is equal to the given target, simply return true. As, all the subsets needs to generated, recursion can be used to solve this problem.
So, f(ind, target) will check whether a subset exists in the array from index 0 to index 'ind' such that the sum of elements is equal to the target.
Do not include the current element in the subset: First try to find a subset without considering the current index element. For this, make a recursive call to f(ind-1,target).
Include the current element in the subset: Now try to find a subset by considering the current index element as part of subset. As the current element(arr[ind]) is included, the remaining target sum will be target - arr[ind]. Therefore, make a function call of f(ind-1,target-arr[ind]).
Note: Consider the current element in the subset only when the current element is less or equal to the target.
/*It is pseudocode and it is not tied to
any specific programming language*/
f(ind, target){
not pick = f(ind-1, target)
pick = false
if(target <= arr[ind]{
pick = f(ind-1, target - arr[ind])
}
}
/*It is pseudocode and it is not tied to
any specific programming language*/
f(ind, target){
not pick = f(ind-1, target)
pick = false
if(target <= arr[ind]{
pick = f(ind-1, target - arr[ind])
}
return (pick || not pick)
}
#include <bits/stdc++.h>
using namespace std;
class Solution{
private:
/* Function to check if there is a subset of arr
with a sum equal to 'target' using recusion*/
bool func(int ind, int target, vector<int>& arr) {
// Base cases
if (target == 0)
return true;
if (ind == 0)
return arr[0] == target;
// Try not taking the current element into subset
bool notTaken = func(ind - 1, target, arr);
/* Try taking the current element into the
subset if it doesn't exceed the target*/
bool taken = false;
if (arr[ind] <= target)
taken = func(ind - 1, target - arr[ind], arr);
// Return the result
return notTaken || taken;
}
public:
/* Function to check if there is a subset
of 'arr' with a sum equal to 'target'*/
bool isSubsetSum(vector<int>& arr, int target) {
// Return the result
return func(arr.size() - 1, target, arr);
}
};
int main() {
vector<int> arr = {1, 2, 3, 4};
int target = 4;
//Create an instance of Solution class
Solution sol;
// Call the subsetSumToK function and print the result
if (sol.isSubsetSum(arr, target))
cout << "Subset with the given target found";
else
cout << "Subset with the given target not found";
return 0;
}
import java.util.*;
class Solution {
/* Function to check if there is a subset of
arr with sum equal to 'target' using recursion*/
private boolean func(int ind, int target, int[] arr) {
// Base cases
if (target == 0)
return true;
if (ind == 0)
return arr[0]== target;
// Try not taking the current element into subset
boolean notTaken = func(ind - 1, target, arr);
/* Try taking the current element into the
subset if it doesn't exceed the target*/
boolean taken = false;
if (arr[ind] <= target)
taken = func(ind - 1, target - arr[ind], arr);
// Return the result
return notTaken || taken;
}
/* Function to check if there is a subset
of 'arr' with sum equal to 'target'*/
public boolean isSubsetSum(int[] arr, int target) {
// Return the result
return func(arr.length - 1, target, arr);
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4};
int target = 4;
// Create an instance of Solution class
Solution sol = new Solution();
// Call the isSubsetSum function and print the result
if (sol.isSubsetSum(arr, target))
System.out.println("Subset with the given target found");
else
System.out.println("Subset with the given target not found");
}
}
class Solution:
""" Function to check if there is a subset of arr
with sum equal to 'target' using recursion"""
def func(self, ind, target, arr):
# Base cases
if target == 0:
return True
if ind == 0:
return arr[0] == target
# Try not taking the current element into subset
notTaken = self.func(ind - 1, target, arr)
""" Try taking the current element into the
subset if it doesn't exceed the target"""
taken = False
if arr[ind] <= target:
taken = self.func(ind - 1, target - arr[ind], arr)
# Return the result
return notTaken or taken
""" Function to check if there is a subset
of 'arr' with sum equal to 'target'"""
def isSubsetSum(self, arr, target):
# Return the result
return self.func(len(arr) - 1, target, arr)
if __name__ == "__main__":
arr = [1, 2, 3, 4]
target = 4
# Create an instance of Solution class
sol = Solution()
# Call the isSubsetSum function and print the result
if sol.isSubsetSum(arr, target):
print("Subset with the given target found")
else:
print("Subset with the given target not found")
class Solution {
/* Function to check if there is a subset of arr
with sum equal to 'target' using recursion*/
func(ind, target, arr) {
// Base cases
if (target === 0)
return true;
if (ind === 0)
return arr[0] === target;
// Try not taking the current element into subset
let notTaken = this.func(ind - 1, target, arr);
/* Try taking the current element into the
subset if it doesn't exceed the target*/
let taken = false;
if (arr[ind] <= target)
taken = this.func(ind - 1, target - arr[ind], arr);
// Return the result
return notTaken || taken;
}
/* Function to check if there is a subset
of 'arr' with sum equal to 'target'*/
isSubsetSum(arr, target) {
// Return the result
return this.func(arr.length - 1, target, arr);
}
}
let arr = [1, 2, 3, 4];
let target = 4;
// Create an instance of Solution class
let sol = new Solution();
// Call the isSubsetSum function and print the result
if (sol.isSubsetSum(arr, target))
console.log("Subset with the given target found");
else
console.log("Subset with the given target not found");
If we draw the recursion tree, we will see that there are overlapping subproblems. Hence the DP approaches can be applied to the recursive solution.
The dp array stores the calculations of subproblems. Initialize dp array with -1, to indicate that no subproblem has been solved yet.
#include <bits/stdc++.h>
using namespace std;
class Solution{
private:
/* Function to check if there is a subset of arr
with a sum equal to 'target' using memoization*/
bool func(int ind, int target, vector<int>& arr, vector<vector<int>>& dp) {
// Base cases
if (target == 0)
return true;
if (ind == 0)
return arr[0] == target;
/* If the result for this subproblem has
already been computed, return it*/
if (dp[ind][target] != -1)
return dp[ind][target];
// Try not taking the current element into subset
bool notTaken = func(ind - 1, target, arr, dp);
/* Try taking the current element into the
subset if it doesn't exceed the target*/
bool taken = false;
if (arr[ind] <= target)
taken = func(ind - 1, target - arr[ind], arr, dp);
/* Store the result in the dp
array to avoid recomputation*/
return dp[ind][target] = notTaken || taken;
}
public:
/* Function to check if there is a subset
of 'arr' with a sum equal to 'target'*/
bool isSubsetSum(vector<int>& arr, int target) {
// Initialize a 2D DP array for memoization
vector<vector<int>> dp(arr.size(), vector<int>(target + 1, -1));
// Return the result
return func(arr.size() - 1, target, arr, dp);
}
};
int main() {
vector<int> arr = {1, 2, 3, 4};
int target = 4;
//Create an instance of Solution class
Solution sol;
// Call the subsetSumToK function and print the result
if (sol.isSubsetSum(arr, target))
cout << "Subset with the given target found";
else
cout << "Subset with the given target not found";
return 0;
}
import java.util.*;
class Solution {
/* Function to check if there is a subset of
arr with sum equal to 'target' using memoization*/
private boolean func(int ind, int target, int[] arr, int[][] dp) {
// Base cases
if (target == 0)
return true;
if (ind == 0)
return arr[0]== target;
/* If the result for this subproblem has
already been calculated, return it*/
if (dp[ind][target] != -1)
return dp[ind][target] == 0 ? false : true;
// Try not taking the current element into subset
boolean notTaken = func(ind - 1, target, arr, dp);
/* Try taking the current element into the
subset if it doesn't exceed the target*/
boolean taken = false;
if (arr[ind] <= target)
taken = func(ind - 1, target - arr[ind], arr, dp);
/* Store the result in the DP table and
return whether either option was successful*/
dp[ind][target] = notTaken || taken ? 1 : 0;
return notTaken || taken;
}
/* Function to check if there is a subset
of 'arr' with sum equal to 'target'*/
public boolean isSubsetSum(int[] arr, int target) {
// Declare a DP table with dimensions [n][k+1]
int dp[][] = new int[arr.length][target + 1];
// Initialize DP table with -1
for (int row[] : dp)
Arrays.fill(row, -1);
// Return the result
return func(arr.length - 1, target, arr, dp);
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4};
int target = 4;
// Create an instance of Solution class
Solution sol = new Solution();
// Call the isSubsetSum function and print the result
if (sol.isSubsetSum(arr, target))
System.out.println("Subset with the given target found");
else
System.out.println("Subset with the given target not found");
}
}
class Solution:
""" Function to check if there is a subset of arr
with sum equal to 'target' using memoization"""
def func(self, ind, target, arr, dp):
# Base cases
if target == 0:
return True
if ind == 0:
return arr[0] == target
""" Check if the result for this combination of
'ind' and 'target' has already been computed"""
if dp[ind][target] != -1:
return dp[ind][target]
# Try not taking the current element into subset
notTaken = self.func(ind - 1, target, arr, dp)
""" Try taking the current element into the
subset if it doesn't exceed the target"""
taken = False
if arr[ind] <= target:
taken = self.func(ind - 1, target - arr[ind], arr, dp)
# Return the result
return notTaken or taken
""" Function to check if there is a subset
of 'arr' with sum equal to 'target'"""
def isSubsetSum(self, arr, target):
# Initialize a memoization table with -1.
dp = [[-1 for j in range(target + 1)] for i in range(len(arr))]
# Return the result
return self.func(len(arr) - 1, target, arr, dp)
if __name__ == "__main__":
arr = [1, 2, 3, 4]
target = 4
# Create an instance of Solution class
sol = Solution()
# Call the isSubsetSum function and print the result
if sol.isSubsetSum(arr, target):
print("Subset with the given target found")
else:
print("Subset with the given target not found")
class Solution {
/* Function to check if there is a subset of arr
with sum equal to 'target' using memoization*/
func(ind, target, arr, dp) {
// Base cases
if (target === 0)
return true;
if (ind === 0)
return arr[0] === target;
/* If the result for this subproblem has
already been calculated, return it*/
if (dp[ind][target] != -1)
return dp[ind][target] == 0 ? false : true;
// Try not taking the current element into subset
let notTaken = this.func(ind - 1, target, arr, dp);
/* Try taking the current element into the
subset if it doesn't exceed the target*/
let taken = false;
if (arr[ind] <= target)
taken = this.func(ind - 1, target - arr[ind], arr, dp);
// Return the result
return dp[ind][target] = notTaken || taken;
}
/* Function to check if there is a subset
of 'arr' with sum equal to 'target'*/
isSubsetSum(arr, target) {
/* Initialize a 2D array 'dp'
to memoize subproblem results*/
const dp = new Array(arr.length);
for (let i = 0; i < arr.length; i++) {
dp[i] = new Array(target + 1).fill(-1);
}
// Return the result
return this.func(arr.length - 1, target, arr, dp);
}
}
let arr = [1, 2, 3, 4];
let target = 4;
// Create an instance of Solution class
let sol = new Solution();
// Call the isSubsetSum function and print the result
if (sol.isSubsetSum(arr, target))
console.log("Subset with the given target found");
else
console.log("Subset with the given target not found");
In order to convert a recursive code to tabulation code, we try to convert the recursive code to tabulation and here are the steps:
The first row dp[0][] indicates that only the first element of the array is considered, therefore for the target value equal to arr[0], only cell with that target will be true, so explicitly set dp[0][arr[0]] =true, (dp[0][arr[0]] means that we are considering the first element of the array with the target equal to the first element itself). Please note that it can happen that arr[0]>target, so we first check it: if(arr[0]<=target) then set dp[0][arr[0]] = true.
#include <bits/stdc++.h>
using namespace std;
class Solution{
private:
/* Function to check if there is a
subset of 'arr' with a sum equal to 'k'*/
bool func(int n, int target, vector<int> &arr) {
/* Initialize a 2D DP array with dimensions
(n x target+1) to store subproblem results*/
vector<vector<bool>> dp(n, vector<bool>(target + 1, false));
// Base case(when target = 0)
for (int i = 0; i < n; i++) {
dp[i][0] = true;
}
/* Base case (If the first element of 'arr' is less
than or equal to 'target', set dp[0][arr[0]] to true)*/
if (arr[0] <= target) {
dp[0][arr[0]] = true;
}
// Fill the DP array iteratively
for (int ind = 1; ind < n; ind++) {
for (int i = 1; i <= target; i++) {
/* If we don't take the current element, the
result is the same as the previous row*/
bool notTaken = dp[ind - 1][target];
/* If we take the current element, subtract its
value from the target and check the previous row*/
bool taken = false;
if (arr[ind] <= target) {
taken = dp[ind - 1][target - arr[ind]];
}
/* Store the result in the DP
array for the current subproblem*/
dp[ind][target] = notTaken || taken;
}
}
// The final result is stored in dp[n-1][k]
return dp[n - 1][target];
}
public:
/*Function to check if there is a subset
of 'arr' with sum equal to 'target'*/
int isSubsetSum(vector<int> arr, int target){
//Return the result
return func(arr.size(), target, arr);
}
};
int main() {
vector<int> arr = {1, 2, 3, 4};
int target = 4;
//Create an instance of Solution class
Solution sol;
// Call the function and print the result
if (sol.isSubsetSum(arr, target))
cout << "Subset with the given target found";
else
cout << "Subset with the given target not found";
return 0;
}
import java.util.*;
class Solution {
/* Function to check if there is a subset
of 'arr' with sum equal to 'target'*/
private boolean func(int n, int target, int[] arr) {
/* Initialize a 2D DP array with dimensions
(n x target+1) to store subproblem results*/
boolean[][] dp = new boolean[n][target + 1];
// Base case (when target = 0)
for (int i = 0; i < n; i++) {
dp[i][0] = true;
}
/* Base case (If the first element of
'arr' is less than or equal to 'target')*/
if (arr[0] <= target) {
dp[0][arr[0]] = true;
}
// Fill the DP array iteratively
for (int ind = 1; ind < n; ind++) {
for (int i = 1; i <= target; i++) {
/* If we don't take the current element, the
result is the same as the previous row*/
boolean notTaken = dp[ind - 1][i];
/* If we take the current element, subtract its
value from the target and check the previous row*/
boolean taken = false;
if (arr[ind] <= i) {
taken = dp[ind - 1][i - arr[ind]];
}
/* Store the result in the DP
array for the current subproblem*/
dp[ind][i] = notTaken || taken;
}
}
// The final result is stored in dp[n-1][target]
return dp[n - 1][target];
}
/* Function to check if there is a subset
of 'arr' with sum equal to 'target'*/
public boolean isSubsetSum(int[] arr, int target) {
// Return the result
return func(arr.length, target, arr);
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4};
int target = 4;
// Create an instance of Solution class
Solution sol = new Solution();
// Call the isSubsetSum function and print the result
if (sol.isSubsetSum(arr, target))
System.out.println("Subset with the given target found");
else
System.out.println("Subset with the given target not found");
}
}
class Solution:
""" Function to check if there is a subset
of 'arr' with sum equal to 'target'"""
def func(self, n, target, arr):
""" Initialize a 2D DP array with dimensions
(n x target+1) to store subproblem results"""
dp = [[False] * (target + 1) for _ in range(n)]
# Base case (when target = 0)
for i in range(n):
dp[i][0] = True
""" Base case (If the first element of 'arr'
is less than or equal to 'target')"""
if arr[0] <= target:
dp[0][arr[0]] = True
# Fill the DP array iteratively
for ind in range(1, n):
for i in range(1, target + 1):
""" If we don't take the current element, the
result is the same as the previous row"""
notTaken = dp[ind - 1][i]
""" If we take the current element, subtract its
value from the target and check the previous row"""
taken = False
if arr[ind] <= i:
taken = dp[ind - 1][i - arr[ind]]
""" Store the result in the DP
array for the current subproblem"""
dp[ind][i] = notTaken or taken
# The final result is stored in dp[n-1][target]
return dp[n - 1][target]
""" Function to check if there is a subset
of 'arr' with sum equal to 'target'"""
def isSubsetSum(self, arr, target):
# Return the result
return self.func(len(arr), target, arr)
if __name__ == "__main__":
arr = [1, 2, 3, 4]
target = 4
# Create an instance of Solution class
sol = Solution()
# Call the isSubsetSum function and print the result
if sol.isSubsetSum(arr, target):
print("Subset with the given target found")
else:
print("Subset with the given target not found")
class Solution {
/* Function to check if there is a subset
of 'arr' with a sum equal to 'target'*/
func(n, target, arr) {
/* Initialize a 2D DP array with dimensions
(n x target+1) to store subproblem results*/
let dp = new Array(n).fill(null).map(() => new Array(target + 1).fill(false));
// Base case (when target = 0)
for (let i = 0; i < n; i++) {
dp[i][0] = true;
}
/* Base case (If the first element of
'arr' is less than or equal to 'target')*/
if (arr[0] <= target) {
dp[0][arr[0]] = true;
}
// Fill the DP array iteratively
for (let ind = 1; ind < n; ind++) {
for (let i = 1; i <= target; i++) {
/* If we don't take the current element, the
result is the same as the previous row*/
let notTaken = dp[ind - 1][i];
/* If we take the current element, subtract its
value from the target and check the previous row*/
let taken = false;
if (arr[ind] <= i) {
taken = dp[ind - 1][i - arr[ind]];
}
/* Store the result in the DP
array for the current subproblem*/
dp[ind][i] = notTaken || taken;
}
}
// The final result is stored in dp[n-1][target]
return dp[n - 1][target];
}
/* Function to check if there is a subset
of 'arr' with sum equal to 'target'*/
isSubsetSum(arr, target) {
// Return the result
return this.func(arr.length, target, arr);
}
}
let arr = [1, 2, 3, 4];
let target = 4;
// Create an instance of Solution class
let sol = new Solution();
// Call the isSubsetSum function and print the result
if (sol.isSubsetSum(arr, target))
console.log("Subset with the given target found");
else
console.log("Subset with the given target not found");
If we observe the relation obtained in the tabulation, dp[ind][target] = dp[ind-1][target] || dp[ind-1][target-arr[ind]]. We see that to calculate a value of a cell of the dp array, we need only the previous row values (say prev). So, we don’t need to store an entire array. Hence we can space optimize it.
#include <bits/stdc++.h>
using namespace std;
class Solution{
private:
/* Function to check if there is a subset
of 'arr' with a sum equal to 'target'*/
bool func(int n, int target, vector<int> &arr) {
/* Initialize a vector 'prev' to store
the previous row of the DP table*/
vector<bool> prev(target + 1, false);
/* Base case: If the target sum is 0, we
can always achieve it by taking no elements*/
prev[0] = true;
/* Base case: If the first element of 'arr' is less
than or equal to 'target', set prev[arr[0]] to true*/
if (arr[0] <= target) {
prev[arr[0]] = true;
}
/* Iterate through the elements
of 'arr' and update the DP table*/
for (int ind = 1; ind < n; ind++) {
/* Initialize a new row 'cur' to store
the current state of the DP table*/
vector<bool> cur(target + 1, false);
/* Base case: If the target sum is 0,
we can achieve it by taking no elements*/
cur[0] = true;
for (int i = 1; i <= target; i++) {
/* If we don't take the current element, the
result is the same as the previous row*/
bool notTaken = prev[i];
/* If we take the current element, subtract its
value from the target and check the previous row*/
bool taken = false;
if (arr[ind] <= i) {
taken = prev[i - arr[ind]];
}
/* Store the result in the current DP
table row for the current subproblem*/
cur[i] = notTaken || taken;
}
/* Update 'prev' with the curren
t row 'cur' for the next iteration*/
prev = cur;
}
// The final result is stored in prev[target]
return prev[target];
}
public:
/* Function to check if there is a subset
of 'arr' with a sum equal to 'target'*/
int isSubsetSum(vector<int> &arr, int target){
//Return the result
return func(arr.size(), target, arr);
}
};
int main() {
vector<int> arr = {1, 2, 3, 4};
int target = 4;
//Create an instance of Solution class
Solution sol;
// Call the function and print the result
if (sol.isSubsetSum(arr, target))
cout << "Subset with the given target found";
else
cout << "Subset with the given target not found";
return 0;
}
import java.util.*;
class Solution {
/* Function to check if there is a subset
of 'arr' with a sum equal to 'target'*/
private boolean func(int n, int target, int[] arr) {
/* Initialize an array 'prev' to store
the previous row of the DP table*/
boolean[] prev = new boolean[target + 1];
/* Base case: If the target sum is 0, we
can always achieve it by taking no elements*/
prev[0] = true;
/* Base case: If the first element of
'arr' is less than or equal to 'target'*/
if (arr[0] <= target) {
prev[arr[0]] = true;
}
/* Iterate through the elements
of 'arr' and update the DP table*/
for (int ind = 1; ind < n; ind++) {
/* Initialize a new array 'cur' to store
the current state of the DP table*/
boolean[] cur = new boolean[target + 1];
/* Base case: If the target sum is 0, we
can achieve it by taking no elements*/
cur[0] = true;
for (int i = 1; i <= target; i++) {
/* If we don't take the current element, the
result is the same as the previous row*/
boolean notTaken = prev[i];
/* If we take the current element, subtract its
value from the target and check the previous row*/
boolean taken = false;
if (arr[ind] <= i) {
taken = prev[i - arr[ind]];
}
/* Store the result in the current DP
table row for the current subproblem*/
cur[i] = notTaken || taken;
}
/* Update 'prev' with the current
row 'cur' for the next iteration*/
prev = cur;
}
// The final result is stored in prev[target]
return prev[target];
}
/* Function to check if there is a subset
of 'arr' with sum equal to 'target'*/
public boolean isSubsetSum(int[] arr, int target) {
// Return the result
return func(arr.length, target, arr);
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4};
int target = 4;
// Create an instance of Solution class
Solution sol = new Solution();
// Call the isSubsetSum function and print the result
if (sol.isSubsetSum(arr, target))
System.out.println("Subset with the given target found");
else
System.out.println("Subset with the given target not found");
}
}
class Solution:
""" Function to check if there is a subset
of 'arr' with a sum equal to 'target'"""
def func(self, n, target, arr):
""" Initialize an array 'prev' to store
the previous row of the DP table"""
prev = [False] * (target + 1)
""" Base case: If the target sum is 0, we
can always achieve it by taking no elements"""
prev[0] = True
""" Base case: If the first element of
'arr' is less than or equal to 'target'"""
if arr[0] <= target:
prev[arr[0]] = True
""" Iterate through the elements of
'arr' and update the DP table"""
for ind in range(1, n):
""" Initialize a new array 'cur' to store
the current state of the DP table"""
cur = [False] * (target + 1)
""" Base case: If the target sum is 0,
we can achieve it by taking no elements"""
cur[0] = True
for i in range(1, target + 1):
""" If we don't take the current element, the
result is the same as the previous row"""
notTaken = prev[i]
""" If we take the current element, subtract its
value from the target and check the previous row"""
taken = False
if arr[ind] <= i:
taken = prev[i - arr[ind]]
""" Store the result in the current DP
table row for the current subproblem"""
cur[i] = notTaken or taken
""" Update 'prev' with the current
row 'cur' for the next iteration"""
prev = cur
# The final result is stored in prev[target]
return prev[target]
""" Function to check if there is a subset
of 'arr' with sum equal to 'target'"""
def isSubsetSum(self, arr, target):
# Return the result
return self.func(len(arr), target, arr)
if __name__ == "__main__":
arr = [1, 2, 3, 4]
target = 4
# Create an instance of Solution class
sol = Solution()
# Call the isSubsetSum function and print the result
if sol.isSubsetSum(arr, target):
print("Subset with the given target found")
else:
print("Subset with the given target not found")
class Solution {
/* Function to check if there is a subset
of 'arr' with a sum equal to 'target'*/
func(n, target, arr) {
/* Initialize an array 'prev' to store
the previous row of the DP table*/
let prev = new Array(target + 1).fill(false);
/* Base case: If the target sum is 0, we
can always achieve it by taking no elements*/
prev[0] = true;
/* Base case: If the first element of
'arr' is less than or equal to 'target'*/
if (arr[0] <= target) {
prev[arr[0]] = true;
}
/* Iterate through the elements of
'arr' and update the DP table*/
for (let ind = 1; ind < n; ind++) {
/* Initialize a new array 'cur' to store
the current state of the DP table*/
let cur = new Array(target + 1).fill(false);
/* Base case: If the target sum is 0,
we can achieve it by taking no elements*/
cur[0] = true;
for (let i = 1; i <= target; i++) {
/* If we don't take the current element, the
result is the same as the previous row*/
let notTaken = prev[i];
/* If we take the current element, subtract its
value from the target and check the previous row*/
let taken = false;
if (arr[ind] <= i) {
taken = prev[i - arr[ind]];
}
/* Store the result in the current DP
table row for the current subproblem*/
cur[i] = notTaken || taken;
}
/* Update 'prev' with the current
row 'cur' for the next iteration*/
prev = cur;
}
// The final result is stored in prev[target]
return prev[target];
}
/* Function to check if there is a subset
of 'arr' with sum equal to 'target'*/
isSubsetSum(arr, target) {
// Return the result
return this.func(arr.length, target, arr);
}
}
// Main function
let arr = [1, 2, 3, 4];
let target = 4;
// Create an instance of Solution class
let sol = new Solution();
if (sol.isSubsetSum(arr, target)) {
console.log("Subset with given target found");
} else {
console.log("Subset with given target not found");
}
Q: Why do we process dp[j] from right to left in the space-optimized approach?
A: Processing from right to left ensures that each element is considered only once per row update, preventing duplicate inclusion.
Q: How is this problem related to the Knapsack problem?
A: Subset Sum is a special case of 0/1 Knapsack, where each element has a value equal to its weight, and the goal is to exactly fill the knapsack.
Q: How would you modify this problem if you needed to return the subset itself?
A: Instead of a boolean table, maintain a backtracking path (dp[i][j] storing previous elements) to reconstruct the subset.
Q: How would you solve this problem in O(n × target / 2) using bit manipulation?
A: Using a bitset, update possible sums efficiently via dp |= (dp << arr[i]).