class Solution {
// Similar to Count of partitions with given difference
/** Recursive code */
public int findTargetSumWays(int[] arr, int target) {
int n = arr.length;
int totalSum = 0;
for(int ele : arr)
totalSum += ele;
// target cannot be larger than possible sum range
if(Math.
abs(target
) > totalSum
) return 0;
// we can't divide if sum is not even
if( (totalSum+target) % 2 != 0)
return 0;
int sum = (totalSum+target)/2;
return findSubsetSum(arr, sum, n);
}
public int findSubsetSum(int[] arr, int sum, int n)
{
if(n == 0)
{
if(sum == 0)
return 1;
return 0;
}
if(arr[n-1] <= sum)
{
int pick = findSubsetSum(arr, sum - arr[n-1], n-1);
int notPick = findSubsetSum(arr, sum, n-1);
return pick + notPick;
}
return findSubsetSum(arr, sum, n-1);
}
/** Memoization code */
public int findTargetSumWays(int[] arr, int target) {
int n = arr.length;
int totalSum = 0;
for(int ele : arr)
totalSum += ele;
// target cannot be larger than possible sum range
if(Math.
abs(target
) > totalSum
) return 0;
// we can't divide if sum is not even
if( (totalSum+target) % 2 != 0)
return 0;
int sum = (totalSum+target)/2;
int[][] t = new int[n+1][sum+1];
for(int i=0; i<n+1; i++)
return findSubsetSum(arr, sum, n, t);
}
public int findSubsetSum(int[] arr, int sum, int n, int[][] t)
{
if(n == 0)
{
if(sum == 0)
return 1;
return 0;
}
if(t[n][sum] != -1)
return t[n][sum];
if(arr[n-1] <= sum)
{
int pick = findSubsetSum(arr, sum - arr[n-1], n-1, t);
int notPick = findSubsetSum(arr, sum, n-1, t);
t[n][sum] = pick + notPick;
return t[n][sum];
}
t[n][sum] = findSubsetSum(arr, sum, n-1, t);
return t[n][sum];
}
/** Top-down approach */
public int findTargetSumWays(int[] arr, int target) {
int n = arr.length;
int totalSum = 0;
for(int ele : arr)
totalSum += ele;
// target cannot be larger than possible sum range
if(Math.
abs(target
) > totalSum
) return 0;
// we can't divide if sum is not even
if( (totalSum+target) % 2 != 0)
return 0;
int sum = (totalSum+target)/2;
int[][] t = new int[n+1][sum+1];
for(int i=0; i<n+1; i++)
{
for(int j=0; j<sum+1; j++)
{
// when array is empty
if(i == 0)
t[i][j] = 0;
// when sum is always 0
if(j == 0)
t[i][j] = 1;
}
}
for(int i=1; i<n+1; i++)
{
for(int j=0; j<sum+1; j++)
{
if(arr[i-1] <= j)
{
int pick = t[i-1][j - arr[i-1]];
int notPick = t[i-1][j];
t[i][j] = pick + notPick;
}
else
t[i][j] = t[i-1][j];
}
}
return t[n][sum];
}
}