[LeetCode] 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 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:
- The length of the given array is positive and will not exceed 20.
- The sum of elements in the given array will not exceed 1000.
- 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
类似题目:
参考资料:
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
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Target Sum 目标和的更多相关文章
- LeetCode Target Sum
原题链接在这里:https://leetcode.com/problems/target-sum/description/ 题目: You are given a list of non-negati ...
- [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 ...
- 494 Target Sum 目标和
给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S.现在你有两个符号 + 和 -.对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面.返回可以使最终数组和为 ...
- Leetcode——Target Sum
Question You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you ha ...
- Leetcode之深度优先搜索(DFS)专题-494. 目标和(Target Sum)
Leetcode之深度优先搜索(DFS)专题-494. 目标和(Target Sum) 深度优先搜索的解题详细介绍,点击 给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S.现在 ...
- [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 ...
- 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 ...
- 59.Target Sum(目标和)
Level: Medium 题目描述: You are given a list of non-negative integers, a1, a2, ..., an, and a target, ...
- Longest subarray of target sum
2018-07-08 13:24:31 一.525. Contiguous Array 问题描述: 问题求解: 我们都知道对于subarray的问题,暴力求解的时间复杂度为O(n ^ 2),问题规模已 ...
随机推荐
- 02-Python的下载和安装_Python编程之路
原文发布在特克斯博客www.susmote.com 之前给大家讲了关于python的背景知识,还有Python的优点和缺点,相信通过之前的介绍很多人已经清楚自己到底要不要选择学习Python,如果已经 ...
- oracle 分析函数中 keep关键字的使用
语法 min | max(column1) keep (dense_rank first | last order by column2) over (partion by column3); 另外f ...
- java枚举类型变通
原始用法 public enum Color { RED, GREEN, BLANK, YELLOW } 开发中用法 public enum ApiCodeEnum { SUCCESS(0," ...
- codeforce round #467(div.2)
A. Olympiad 给出n个数,让你找出有几个非零并且不重复的数 所以用stl的set //#define debug #include<stdio.h> #include<ma ...
- ConcurrentHashMap、synchronized与线程安全
明明用了ConcurrentHashMap,可是始终线程不安全, 下面我们来看代码: public class Test40 { public static void main(String[] ar ...
- Bate版敏捷冲刺每日报告--day1
1 团队介绍 团队组成: PM:齐爽爽(258) 小组成员:马帅(248),何健(267),蔡凯峰(285) Git链接:https://github.com/WHUSE2017/C-team 2 ...
- 学号:201621123032 《Java程序设计》第5周学习总结
1:本周学习总结 1.1: 写出你认为本周学习中比较重要的知识点关键词 接口interface,comparator接口和comparable接口. 1.2:尝试使用思维导图将这些关键词组织起来. 2 ...
- vivado License导入方法与资源获取
前言 以下安装说明基于已经正确安装vivado 笔者操作环境:linux vivado版本:2015.2 vivado License导入方法: 点击菜单栏[Help],选择[Manage Licen ...
- 使用PostMan进行API自动化测试
最近在进行一个老项目的升级,第一步是先将node版本从4.x升级到8.x,担心升级会出现问题,所以需要将服务的接口进行验证:如果手动输入各种URL,人肉check,一个两个还行,整个服务..大几十个接 ...
- installutil 安装windows service
1:路径:C:\Windows\Microsoft.NET\Framework\v4.0.30319 2:执行指令:C:\Windows\Microsoft.NET\Framework\v4.0.30 ...