设添加正号的元素之和为x,添加负号的元素之和为y,给定数组和为sum,目标数是S:
显然有x+y=sum, x-y=S;
所以有x-(sum-x)=S, 即x=(sum+S)/2;
因为给定数组中元素均为整型,如果sum+S是奇数显然 是不成立的。
该问题转化为求部分和为x的子列的个数。
方法一:暴力求解,枚举所有组合的情况,判断部分和是否为x
方法二:动态规划
认为背包容量为x,物品的重量和价值就是给定的对应的元素。题目就转变为求装满容量为x的背包有多少种方法。
用dp[j]代表装满容量为j的背包的方法数。
在背包容量为j时,假如一定要装重量为i的物品,则有dp[j-i]种方法。那么dp[j]就是所有情况的和,也就是dp[j] =
class Solution {
public int findTargetSumWays(int[] nums, int target) {
int sum = 0;
for(int x : nums){
sum += x;
}
if((sum + target) % 2 == 1) return 0;
if(Math.abs(target) > sum) return 0;
int[] dp = new int[(sum + target)/2+1];
dp[0] = 1;
for(int i = 0; i < nums.length; ++i){
for(int j = (sum + target)/2; j >= nums[i]; --j){
dp[j] += dp[j - nums[i]];
}
}
return dp[(sum + target)/2];
}
}