LeetCode/solutions/494. Target Sum.md
2019-11-26 21:26:54 +08:00

1.4 KiB
Raw Blame History

494. Target Sum

思路

这道题给了我们一个数组元素非负和一个目标值要求给数组中每个数字前添加正号或负号所组成的表达式结果与目标值S相等求有多少种情况。

假设所有元素和为sum所有添加正号的元素的和为A所有添加负号的元素和为B则有sum = A + BS = A - B,解方程得A = (sum + S)/2。 即题目转换成:从数组中选取一些元素使和恰好为(sum + S) / 2。可见这是一个恰好装满的01背包问题要求所有方案数。

我在我的博客文章动态规划之背包问题系列对常见的几类背包问题做了个总结此题的分析见5.3节,这里只给出代码。

C++

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int S) {
        int sum = 0;
        // for(int &num: nums) sum += num;
        sum = accumulate(nums.begin(), nums.end(), 0);
        if(S > sum || sum < -S) return 0;
        if((S + sum) & 1) return 0;
        int target = (S + sum) >> 1;
        
        vector<int>dp(target + 1, 0);
        
        dp[0] = 1;
        for(int i = 1; i <= nums.size(); i++)
            for(int j = target; j >= nums[i-1]; j--){
                dp[j] = dp[j] + dp[j - nums[i-1]];
            } 
        
        return dp[target];
    }
};