class Solution {
/** Recursive code */
static Boolean isSubsetSum
(int arr
[],
int sum
) { int n = arr.length;
return findSubsetSum(arr, sum, n);
}
static Boolean findSubsetSum
(int[] arr,
int sum,
int n
) {
// when we reach end of the array, so couldn't found a subset
if(n == 0)
return false;
// when sum becomes 0 that means found a subset
if(sum == 0)
return true;
if(arr[n-1] <= sum)
{
// pick the element in subset
boolean pick = findSubsetSum(arr, sum - arr[n-1], n-1);
// do not pick the element in subset
boolean notPick = findSubsetSum(arr, sum, n-1);
return pick || notPick;
}
// when current element exceeds given sum, so skip the element
return findSubsetSum(arr, sum, n-1);
}
/** Memoization code */
static Boolean isSubsetSum
(int arr
[],
int sum
) { int n = arr.length;
boolean[][] t = new boolean[n+1][sum+1];
// when array of size will increase but sum needs to always 0, then we can have always empty subset
for(int i=0; i<n+1; i++)
{
}
// when sum increases but size of array is always 0, then we cannot have any subset
for(int j=0; j<n+1; j++)
{
}
return findSubsetSum(arr, sum, n, t);
}
static Boolean findSubsetSum
(int[] arr,
int sum,
int n,
boolean[][] t
) {
// when we reach end of the array, so couldn't found a subset
if(n == 0)
return false;
// when sum becomes 0 that means found a subset
if(sum == 0)
return true;
if(t[n][sum] != false)
return t[n][sum];
if(arr[n-1] <= sum)
{
// pick the element in subset
boolean pick = findSubsetSum(arr, sum - arr[n-1], n-1, t);
// do not pick the element in subset
boolean notPick = findSubsetSum(arr, sum, n-1, t);
t[n][sum] = pick || notPick;
return t[n][sum];
}
// when current element exceeds given sum, so skip the element
t[n][sum] = findSubsetSum(arr, sum, n-1, t);
return t[n][sum];
}
/** Top-down approach */
static Boolean isSubsetSum
(int arr
[],
int sum
) { int n = arr.length;
boolean[][] t = new boolean[n+1][sum+1];
// intialise the matrix on basis of base condition
for(int i=0; i<n+1; i++)
{
for(int j=0; j<sum+1; j++)
{
// when sum increases but size of array is always 0, then we cannot have any subset
if(i==0)
{
t[i][j] = false;
}
// when array of size will increase but sum needs to always 0, then we can have always empty subset
if(j==0)
{
t[i][j] = true;
}
}
}
for(int i=1; i<n+1; i++)
{
for(int j=1; j<sum+1; j++)
{
if(arr[i-1] <= j)
{
boolean pick = t[i-1][j - arr[i-1]];
boolean notPick = t[i-1][j];
t[i][j] = pick || notPick;
}
else
t[i][j] = t[i-1][j];
}
}
return t[n][sum];
}
}