494.目标和

494.目标和

给你一个整数数组 nums 和一个整数 target 。

向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :

例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。
返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

示例 1:

输入: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

示例 2:

输入:nums = [1], target = 1
输出:1

提示:
1 <= nums.length <= 20
0 <= nums[i] <= 1000
0 <= sum(nums[i]) <= 1000
-1000 <= target <= 1000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/target-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

题目可以转换为 -> 把数分为两堆,两堆和之差为目标和,求分堆的方法数。

大堆和指元素和大的一堆
sum大堆和 - target = sum总堆和 - sum大堆和
--> 2*sum大堆和 = sum总堆和 + target
--> sum大堆和 = (sum总堆和 + target)/2

注意点1:
如果sum总堆和 + target是奇数,那么直接返回0,因为元素都是整数,sum大堆和不能出现小数。
注意点2:
如果target比sum总堆和都还要大,那么结果肯定是不满足的
注意点3:
target可以为负数,也就是 sum总堆和 - sum大堆和 - sum大堆和 = target
--> sum大堆和 = (sum总堆和 - target)/2

综合上述两种情况,sum大堆和 = (sum总堆和 + |target|)/2

可以转化为-> 背包的容量 (sum总堆和 + |target|)/2,物品的重量为nums[i],物品的价值nums[i]。

可以转化为 -> 该背包有几种装法,组合问题

1.确定dp数组以及下标的含义
dp[j] 表示填满背包容量j有dp[j]种方法。

2.确定递推公式

有哪些来源可以推出dp[j]

  • 填满j-nums[i]的背包有dp[j-nums[i]]种方法,也就是如果当前nums[i]放入背包那么就有dp[j-nums[i]]种方法
  • 之前填满容量为j背包的方法数

两种方法都可以选择,那么dp[j] = dp[j] + dp[j-nums[i]]

3.dp数组如何初始化
dp[0] = 1,有一种装法

4.确定遍历顺序

先遍历物品
再遍历背包容量

for(int i=0;i<len;i++){
	for(int j=bagWeight;j>=nums[i];j--){
		dp[j] = dp[j] + dp[j-nums[i]]
	}
}

5.举例推导dp数组
输入:nums = [1,1,1,1,1], target = 3
image

代码

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        for(int num : nums){
            sum +=num;
        }
        target = Math.abs(target);
        if(sum < target) return 0;
        if((sum + target)%2 == 1) return 0;
        target = (sum + target)/2;
        int [] dp = new int [target+1];
        dp[0]=1;
        for(int i=0;i<nums.length;i++){
            for(int j=target;j>=nums[i];j--){
                dp[j] += dp[j-nums[i]];     
            }
        }
        return dp[target];
    }
}
posted @ 2021-09-08 11:00  rananie  阅读(115)  评论(0编辑  收藏  举报