/**
* s1-s2 = diff -- (1)
* s1+s2 = totalSum -- (2)
* s2 = totalSum-s1
* s1 - (totalSum - s1) = diff
* 2s1 - totalSum = diff
* 2s1 = diff + totalSum
* s1 = (diff+totalSum)/2
*/
/** Recursive code */
public int countPartitions(int[] arr, int diff) {
int n = arr.length;
int totalSum = 0;
for(int ele : arr)
totalSum += ele;
if(diff > totalSum)
return 0;
// we can't divide if sum is not even
if( (diff + totalSum) % 2 != 0)
return 0;
int sum = (totalSum + diff)/2;
return findSubsetSum(arr, sum , n);
}
public int findSubsetSum(int[] arr, int sum, int n)
{
if(n == 0)
return 0;
if(sum == 0)
return 1;
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 countPartitions(int[] arr, int diff) {
int n = arr.length;
int totalSum = 0;
for(int ele : arr)
totalSum += ele;
if(diff > totalSum)
return 0;
// we can't divide if sum is not even
if( (diff + totalSum) % 2 != 0)
return 0;
int sum = (totalSum + diff)/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 code */
public int countPartitions(int[] arr, int diff) {
int n = arr.length;
int totalSum = 0;
for(int ele : arr)
totalSum += ele;
if(diff > totalSum)
return 0;
// we can't divide if sum is not even
if( (diff + totalSum) % 2 != 0)
return 0;
int sum = (totalSum + diff)/2;
int[][] t = new int[n+1][sum+1];
// base condition
for(int i=0; i<n+1; i++)
{
for(int j=0; j<sum+1; j++)
{
// when array is empty, sum increases
if(i == 0)
t[i][j] = 0;
// when sum is always 0, array size increases
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];
}
}