/**
* given an array of positive integers and a target
* find out if there exists a subset(s) that sum up to the target
* subproblems:
* 1. the subset includes nums[n] then return isSubsetSum(n-1, target-nums[n])
* 2. the subset excludes nums[n] then return isSubsetSum(n-1, target)
* anyone of those subproblems is true then return true
* base cases:
* 1. n == 0 && target != 0, return false
* 2. target == 0, return true
*/
public class isSubsetSum {
public static boolean isSubset (int n, int target, int[] nums) {
if (target == 0) return true;
if (n == 0 && target != 0) return false;
return isSubset(n-1, target, nums) || isSubset(n-1, target-nums[n], nums);
}
public static void main(String[] args) {
int[] nums = {1, 5, 11, 5};
int target = 11;
System.out.println(isSubset(nums.length-1, target, nums));
}
}
/**
* transfer the original problem to isSubsetSum problem by:
* sum the arrays, if the sum is an odd value, there is no you can find two subsets with same sum
* if the sum is an even value, half it, and the target is sum/2, array is the original array nums[]
* below is a naive recursive version, will get a TLE
*/
public class Solution {
public boolean isSubsetSum(int n, int target, int[] nums) {
if (n == 0 && target != 0) return false;
if (target == 0) return true;
return isSubsetSum(n-1, target, nums) || isSubsetSum(n-1, target-nums[n], nums);
}
public boolean canPartition(int[] nums) {
int sum = 0;
for (int obj : nums)
sum += obj;
boolean[][] dp = new boolean[nums.length][sum/2+1];
if (sum % 2 == 1) return false;
return isSubsetSum(nums.length-1, sum/2, nums);
}
}
http://www.geeksforgeeks.org/dynamic-programming-subset-sum-problem/