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];
}
}

本文探讨了一道典型的组合问题,即在给定的数字数组中,通过在每个数字前添加‘+’或‘-’符号,寻找所有可能的组合方式,以使最终的和等于指定的目标值。文章提供了一个详细的解决方案,包括如何转换问题为背包问题,以及具体的代码实现。
3048

被折叠的 条评论
为什么被折叠?



