You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols +
and -
. For each integer, you should choose one from +
and -
as its new symbol.
Find out how many ways to assign symbols to make sum of integers equal to target S.
Example 1:
Input: nums is [1, 1, 1, 1, 1], S is 3. Output: 5 Explanation: -1+1+1+1+1 = 3 +1-1+1+1+1 = 3 +1+1-1+1+1 = 3 +1+1+1-1+1 = 3 +1+1+1+1-1 = 3 There are 5 ways to assign symbols to make the sum of nums be target 3.
Note:
- The length of the given array is positive and will not exceed 20.
- The sum of elements in the given array will not exceed 1000.
- Your output answer is guaranteed to be fitted in a 32-bit integer.
题意:给出一串数字数组nums[ ]和一个目标和S,求有多少种组合方式能在每个数前添加‘ + ’或‘ - ’ ,使最后的和等于目标和S。
思路:从网上学到的解题思路如下:
将数组分成正数和负数两个子数组,分别命名P[ ]和N[ ],正数的和为sum(P),负数的和sum(N),
根据推算可得出以下结论:
因此将解题思路转变为数组中的部分数字有多少种方式组合得到 sum(P) ,变成背包问题。
因此,sum(P)能被组合的数量 = sum(P)-num 能被组合的累加和,(num是nums数组中的每一个数)
代码:
class Solution {
public int findTargetSumWays(int[] nums, int S) {
int sum=S;
for(int n : nums){
sum+=n;
}
//如果数组和+目标数的和为奇数时 或 数组和小于目标和时 ,肯定不能被组合
if(sum%2 == 1 || sum<2*S)
return 0;
sum /= 2;
int[] dp = new int[sum+1];
dp[0] = 1;
for(int n: nums){
for(int i=sum;i>=n;i--){
dp[i] += dp[i-n];
}
}
return dp[sum];
}
}