LeetCode 题解:494. Target Sum

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:
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.

解题思路

这道题使用动态规划加哈希表解决。每添加一个加数(或减数),可以看作是在前面运算的结果集中加上(或减去)当前数字,那么得到的新结果的方法数就是结果集能得到此结果的所有元素对应的方法数的和。算法步骤如下:
1、rec 哈希表记录出现过的运算结果的次数
2、每一次从 nums 数组中取出一个数时,都与 rec 中记录的所有结果做一次 “+” 和 “-” 的运算,得到新的运算结果 res
3、假如当前的新运算结果不存在于 rec ,那么将其作为元素添加到 rec 中;否则,rec[res] 加上 nums[i] 所记录的值
4、nums 数组遍历完成后,rec[S] 即为所求。
语句 ptr->second == 0? 1 : ptr->second; 是为了处理如 [0,0,0,0,0,1] 1 这类输入

C++代码

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int S) {
        map<int, int> rec;
        rec[0] = 0;
        for(int i = 0; i < nums.size(); i++) {
            map<int, int> rec1;
            for(map<int, int>::iterator ptr = rec.begin(); ptr != rec.end(); ptr++) {
                int n = ptr->first + nums[i], m = ptr->first - nums[i];
                if(rec1.find(n) == rec1.end()) {
                    rec1[n] = ptr->second == 0? 1 : ptr->second;
                }
                else {
                    rec1[n] += ptr->second == 0? 1 : ptr->second;
                }
                if(rec1.find(m) == rec1.end()) {
                    rec1[m] = ptr->second == 0? 1 : ptr->second;
                }
                else {
                    rec1[m] += ptr->second == 0? 1 : ptr->second;
                }
            }
            rec = rec1;
        }
        return rec[S];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZTao-z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值