题目描述
给定一个非负整数数组,a1, a2, …, an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。
返回可以使最终数组和为目标数 S 的所有添加符号的方法数。
示例 1:
输入: nums: [1, 1, 1, 1, 1], S: 3
输出: 5
解释:
-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
一共有5种方法让最终目标和为3。
注意:
- 数组的长度不会超过20,并且数组中的值全为正数。
- 初始的数组的和不会超过1000。
- 保证返回的最终结果为32位整数。
题解
使用DFS遍历出所有结果
class Solution {
int result=0;
public void find(int[] nums,int S,int cur,int res){
if(cur==nums.length){
if(res==S){
result++;
}
}else{
find(nums,S,cur+1,res+nums[cur]);
find(nums,S,cur+1,res-nums[cur]);
}
}
public int findTargetSumWays(int[] nums, int S) {
find(nums,S,0,0);
return result;
}
}
根据DP的思想求解
class Solution {
public int findTargetSumWays(int[] nums, int S) {
if(nums == null)
return 0;
int sum = 0;
for(int num : nums)
sum += num;
if(S > sum || (sum + S)%2 == 1)
return 0;
sum = (sum + S)/2;
int[] dp = new int[sum+1];
dp[0] = 1;
for(int i = 0; i < nums.length; i++){
for(int j = sum; j >= nums[i]; j--){
dp[j] += dp[j-nums[i]];
}
}
return dp[sum];
}
}