题目:
给定一个正整数数组 nums 和一个整数 target 。
向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :
例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。
返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。
示例 :
输入:nums = [1,1,1,1,1], target = 3
输出:5
解释:一共有 5 种方法让最终目标和为 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
+1 + 1 + 1 + 1 - 1 = 3
思路:
只需要给出种数不需要具体方案,否则就应该使用回溯方法
还是01背包,具体见代码
复杂度:
时间:双重循环O(n^2)。
空间:O(n)。
代码:
public int findTargetSumWays(int[] nums, int target) {
//还是01背包问题
int sum = 0;
for(int num: nums){
sum +=num;
}
//目标比总数大,不可能
if(target > sum) return 0;
if( (target+sum) % 2 == 1) return 0;
int size =(target+sum)/2;
//dp[i]表示填满i容量的包,有dp[i]中方法
int[] dp = new int[size+1];
dp[0] = 1;
//推公式,分为考不考虑nums[i]的情况,不考虑的话,也就是填j-nums[i]的包,有dp[j-nums[i]]种方法
//考虑的话也就是 dp[j] +=dp[j-nums[i]]
for(int i = 0;i<nums.length;i++){
for(int j =size;j>=nums[i];--j){
dp[j] +=dp[j-nums[i]];
}
}
return dp[size];
}