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

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.

Note:

    1. The length of the given array is positive and will not exceed 20.
    2. The sum of elements in the given array will not exceed 1000.
    3. Your output answer is guaranteed to be fitted in a 32-bit integer.

这道题给了我们一个数组,和一个目标值,让给数组中每个数字加上正号或负号,然后求和要和目标值相等,求有多少中不同的情况。那么对于这种求多种情况的问题,博主最想到的方法使用递归来做。从第一个数字,调用递归函数,在递归函数中,分别对目标值进行加上当前数字调用递归,和减去当前数字调用递归,这样会涵盖所有情况,并且当所有数字遍历完成后,若目标值为0了,则结果 res 自增1,参见代码如下:

解法一:

class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
int res = ;
helper(nums, S, , res);
return res;
}
void helper(vector<int>& nums, long S, int start, int& res) {
if (start >= nums.size()) {
if (S == ) ++res;
return;
}
helper(nums, S - nums[start], start + , res);
helper(nums, S + nums[start], start + , res);
}
};

我们对上面的递归方法进行优化,使用 memo 数组来记录中间值,这样可以避免重复运算,参见代码如下:

解法二:

class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
vector<unordered_map<int, int>> memo(nums.size());
return helper(nums, S, , memo);
}
int helper(vector<int>& nums, long sum, int start, vector<unordered_map<int, int>>& memo) {
if (start == nums.size()) return sum == ;
if (memo[start].count(sum)) return memo[start][sum];
int cnt1 = helper(nums, sum - nums[start], start + , memo);
int cnt2 = helper(nums, sum + nums[start], start + , memo);
return memo[start][sum] = cnt1 + cnt2;
}
};

我们也可以使用迭代的方法来解,使用一个 dp 数组,其中 dp[i][j] 表示到第 i-1 个数字且和为j的情况总数,参见代码如下:

解法三:

class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
int n = nums.size();
vector<unordered_map<int, int>> dp(n + );
dp[][] = ;
for (int i = ; i < n; ++i) {
for (auto &a : dp[i]) {
int sum = a.first, cnt = a.second;
dp[i + ][sum + nums[i]] += cnt;
dp[i + ][sum - nums[i]] += cnt;
}
}
return dp[n][S];
}
};

我们也可以对上面的方法进行空间上的优化,只用一个 HashMap,而不是用一个数组的哈希表,在遍历数组中的每一个数字时,新建一个 HashMap,在遍历原 HashMap 中的项时更新这个新建的 HashMap,最后把新建的 HashMap 整个赋值为原 HashMap,参见代码如下:

解法四:

class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
unordered_map<int, int> dp;
dp[] = ;
for (int num : nums) {
unordered_map<int, int> t;
for (auto a : dp) {
int sum = a.first, cnt = a.second;
t[sum + num] += cnt;
t[sum - num] += cnt;
}
dp = t;
}
return dp[S];
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/494

类似题目:

Expression Add Operators

参考资料:

https://leetcode.com/problems/target-sum/

https://leetcode.com/problems/target-sum/discuss/97371/Java-Short-DFS-Solution

https://leetcode.com/problems/target-sum/discuss/97369/Evolve-from-brute-force-to-dp

https://leetcode.com/problems/target-sum/discuss/97334/Java-(15-ms)-C%2B%2B-(3-ms)-O(ns)-iterative-DP-solution-using-subset-sum-with-explanation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Target Sum 目标和的更多相关文章

  1. LeetCode Target Sum

    原题链接在这里:https://leetcode.com/problems/target-sum/description/ 题目: You are given a list of non-negati ...

  2. [LeetCode] 494. Target Sum 目标和

    You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symb ...

  3. 494 Target Sum 目标和

    给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S.现在你有两个符号 + 和 -.对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面.返回可以使最终数组和为 ...

  4. Leetcode——Target Sum

    Question You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you ha ...

  5. Leetcode之深度优先搜索(DFS)专题-494. 目标和(Target Sum)

    Leetcode之深度优先搜索(DFS)专题-494. 目标和(Target Sum) 深度优先搜索的解题详细介绍,点击 给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S.现在 ...

  6. [Leetcode] DP -- Target Sum

    You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symb ...

  7. LN : leetcode 494 Target Sum

    lc 494 Target Sum 494 Target Sum You are given a list of non-negative integers, a1, a2, ..., an, and ...

  8. 59.Target Sum(目标和)

    Level:   Medium 题目描述: You are given a list of non-negative integers, a1, a2, ..., an, and a target, ...

  9. Longest subarray of target sum

    2018-07-08 13:24:31 一.525. Contiguous Array 问题描述: 问题求解: 我们都知道对于subarray的问题,暴力求解的时间复杂度为O(n ^ 2),问题规模已 ...

随机推荐

  1. [jdoj1817]Drainage Ditches_网络流

    Drainage Ditches jdoj-1817 题目大意:网络流裸求最大流 注释:n(点数),m(边数)<=200. 想法:裸的网络流求最大流,用bfs+dfs,美其名曰dinic. 没有 ...

  2. QueryBuilder 前端构造SQL条件的插件使用方法

    页面引入JS等: <script type="text/javascript" src="/qysds-jx/pages/gzrw/js/jquery.js&quo ...

  3. Jquery判断checkbox是否被选中

    jQuery中: $("input[type='checkbox']").is(':checked') 返回true或false 1.attr()方法  设置或者返回备选元素的值 ...

  4. 漫谈Java IO之普通IO流与BIO服务器

    今天来复习一下基础IO,也就是最普通的IO. 网络IO的基本知识与概念 普通IO以及BIO服务器 NIO的使用与服务器Hello world Netty的使用与服务器Hello world 输入流与输 ...

  5. sys模块的使用

    import sys,time ''' if sys.argv[1]=='sleepy': print('nongsi') else: print('....')''' #进度条 for i in r ...

  6. 修改MYSQL的默认连接时长

    show global variables like 'wait_timeout'; 设置成10小时; set global wait_timeout=36000;

  7. 纯CSS垂直居中的四种解决方案

    总结了几种解决方法 但也不是说除了我说的就没有其他方法了 第一个.利用flex布局 代码: 效果: 第二个.利用transform 的 translate属性 代码: 效果: 第三个.使用伪类::af ...

  8. LeetCode & Q268-Missing Number-Easy

    Array Math Bit Manipulation Description: Given an array containing n distinct numbers taken from 0, ...

  9. HTTP请求到爬虫代码的终南捷径

    前阵子在做爬虫的时候学会了各种抓包,看到http请求的时候硬拼代码实在有点累. 后来发现Postman工具是直接可以把Postman请求直接生成对应的代码,这样一下来就美滋滋了. 那么最后的问题就成了 ...

  10. java中类的三大特征之多态

    Java 多态 同一种事物由于条件不同,展示出不同的结果,叫做多态. 父类的引用类型,由于使用不同的子类对象实例,而执行不同的操作. 多态存在的三个必要条件 1. 子类继承父类: 2. 子类重写父类方 ...