算法课第8周第1题——494. Target Sum
来源:互联网 发布:csgo awp 数据 编辑:程序博客网 时间:2024/06/05 07:48
题目描述:
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: 5Explanation: -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 = 3There 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.
class Solution {public:int findTargetSumWays(vector<int>& nums, int S) {// 所有数组中数的总和为sumint sum = 0;for (int i = 0; i < nums.size(); i++) {sum += nums[i];}if (S < -sum || S > sum) {return 0;}// 用一个map(名为dp)来进行动态规划// dp[i]表示运算结果为i的取法数(i值可取正、0、负)。dp[S]即是最终答案map<int, int> dp;for (int i = -sum; i <= sum; i++) {dp[i] = 0;}// 当开始循环前,还没有数能遍历,此时S=0的取法数为1dp[0] = 1;// 外层循环,使内层第1次访问num[0](即输入的第一个数), 第2次访问num[1]....第n次访问num[n-1]for (int i = 0; i < nums.size(); i++) {// temp用于暂时存放,每次外层循环最后会将temp赋给dpmap<int, int> temp;for (int t = -sum; t <= sum; t++) {temp[t] = 0;}// 内层循环。将所有dp的值更新。// 只要j的值不超过[-sum, sum]的范围,或dp[j]不为0(dp[j]为0时不计算,节约时间)// 就可用动态规划计算for (int j = -sum; j <= sum; j++) {if (dp[j] != 0 && j - nums[i] >= -sum && j + nums[i] <= sum) {temp[j - nums[i]] += dp[j];temp[j + nums[i]] += dp[j];}}dp = temp;}return dp[S];}};
简要题解:
本题用到了动态规划的思想。
先理解题意。本题输入为一组整数,通过给这组整数添加+ 或 -,可以运算出一个结果。 求使得最终运算结果为S的取法数。
令sum为输入数组里数字的总和,设dp[i]为结果为i 时的取法数。则i 的取值范围是[-sum, sum]. dp[0]初始化为1, 表示还未开始对输入数组num循环前,结果为0的取法有1种(因为没开始对num循环,所以没有取数,所以最终结果自然就是0)。其余dp的值初始化为0.
接着开始对输入数组num循环(外层循环),使得内层第1次访问num[0] (即输入的第一个数), 第2次访问num[1]....第n次访问num[n-1]
而内层循环则每次都从-sum到sum遍历dp(即遍历dp的所有值)并更新dp的值。用于循环的变量j 正是某几个数的加减计算结果值(所以取值范围才是[-sum, sum])。当访问到num[i]时,由于接下来要减去或加上num[i], 因此会影响dp[j - nums[i]] 和 dp[j + nums[i]]的值(即运算结果为j - nums[i]或 j + nums[i] 时的取法数),因此由动态规划可推得:
dp[j - nums[i]] = dp[j - nums[i]] + dp[j]
dp[j + nums[i]] = dp[j+nums[i]] + dp[j]
这样经过两层的循环,就可以不断更新并得到最终的dp. 而dp[S]正是最终的输出结果(运算结果为S时的取法数)。
本题属于有一些难度的动态规划,我思考的时候花了不少力气,不过理清思路后代码写起来倒还相对容易。动态规划就属于思考起来比较难的题目,要花不少脑筋去想,我感觉自己目前还不够熟练。之后有机会我还会做更多训练。
- 算法课第8周第1题——494. Target Sum
- 算法课第3周第1题——113. Path Sum II
- 算法课第15周第1题—— 416. Partition Equal Subset Sum
- 第四周:( LeetCode494 ) Target Sum(c++)
- 算法课第1周第1题——20. Valid Parentheses
- 算法课第1周第2题——10. Regular Expression Matching
- 算法课第1周第3题——38. Count and Say
- 算法课第2周第1题——100. Same Tree
- 算法课第4周第1题——417. Pacific Atlantic Water Flow
- 算法课第6周第1题——402. Remove K Digits
- 算法课第7周第1题——516. Longest Palindromic Subsequence
- 算法课第9周第1题——474. Ones and Zeroes
- 算法课第10周第1题——70. Climbing Stairs
- 算法课第11周第1题——120. Triangle
- 算法课第12周第1题——62. Unique Paths
- 算法课第13周第1题——486. Predict the Winner
- 算法课第14周第1题——322. Coin Change
- 算法课第17周第1题——133. Clone Graph
- 数据库锁机制
- C语言基础知识(四)
- 欢迎使用CSDN-markdown编辑器
- 跟小博老师一起学习数据库 ——约束(中篇)
- nyoj 304 节能 【区间dp】
- 算法课第8周第1题——494. Target Sum
- C语言指针,数组,函数总结
- BZOJ 3223: Tyvj 1729 文艺平衡树
- 系统调用的实现原理
- Hadoop 学习笔记六 Hadoop2.X 64位编译
- C语言存储类型总结(malloc,typedef)
- 多线程学习
- DAY2 作业设计
- 联想拆机清粉尘之笔记本电脑开机一直就进入bios