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.
因为这里涉及到多种不同的选择,所以很容易联想到用dfs,代码如下:
 class Solution {
public int findTargetSumWays(int[] nums, int S) {
int[] count = { };
helper(nums, , S, count);
return count[];
} private void helper(int[] nums, int index, int S, int[] count) {
if (index == nums.length && S == ) {
count[]++;
}
if (index >= nums.length) return;
helper(nums, index + , S + nums[index], count);
helper(nums, index + , S - nums[index], count);
}
}

但是这种方法明显是没有优化的,所以时间比其他方法要高。简单的优化就是当我们到了i-th这个位置的时候,如果发现后面部分的值的和或者差都不可能达到target值,我们就应该放弃。

 public class Solution {
public int findTargetSumWays(int[] nums, int S) {
if(nums == null || nums.length == ) return ; int n = nums.length;
int[] sums = new int[n];
int[] count = { };
sums[n - ] = nums[n - ];
for (int i = n - ; i >= ; i--) {
sums[i] = sums[i + ] + nums[i];
}
helper(nums, sums, S, , count);
return count[];
}
public void helper(int[] nums, int[] sums, int target, int pos, int[] count){
if(pos == nums.length && target == ){
count[]++;
} if (pos == nums.length) return;
if (sums[pos] < Math.abs(target)) return; helper(nums, sums, target + nums[pos], pos + , count);
helper(nums, sums, target - nums[pos], pos + , count);
}
}

还有就是通过dp来做,解法如下:https://leetcode.com/problems/target-sum/discuss/97335/Short-Java-DP-Solution-with-Explanation

this is a classic knapsack problem
in knapsack, we decide whether we choose this element or not
in this question, we decide whether we add this element or minus it

So start with a two dimensional array dp[i][j] which means the number of ways for first i-th element to reach a sum j

we can easily observe that dp[i][j] = dp[i-1][j+nums[i]] + dp[i-1][j-nums[i],

Another part which is quite confusing is return value, here we return dp[sum+S], why is that?

because dp's range starts from -sum --> 0 --> +sum
so we need to add sum first, then the total starts from 0, then we add S

Actually most of Sum problems can be treated as knapsack problem, hope it helps

 public int findTargetSumWays(int[] nums, int S) {

       int sum = ;
for(int n: nums){
sum += n;
}
if (S < -sum || S > sum) { return ;} int[][] dp = new int[nums.length + ][ * sum + ];
dp[][ + sum] = ; // 0 + sum means 0, 0 means -sum, check below graph
for(int i = ; i <= nums.length; i++){
for(int j = ; j < * sum + ; j++){ if(j + nums[i - ] < * sum + ) dp[i][j] += dp[i - ][j + nums[i - ]];
if(j - nums[i - ] >= ) dp[i][j] += dp[i - ][j - nums[i - ]];
}
}
return dp[nums.length][sum + S];
}

最新文章

  1. centos6.5安装elasticsearch
  2. SQLserver中用convert函数转换日期格式
  3. Java小知识--length,length(),size()方法详细介绍
  4. webpack入坑之旅(三)webpack.config入门
  5. Ubuntu学习总结-08 Ubuntu运行Shell脚本报 shell /bin/bash^M: bad interpreter错误问题解决
  6. 从零开始学Linux[二]:常用操作:用户组、进程、网络、ssh
  7. The content of element type &quot;package&quot; must match &quot;(result-types?,interceptors?...
  8. mysql - 启动错误InnoDB: mmap(137363456 bytes) failed; errno 12
  9. SpringMVC项目接入Springfox实战遇到的问题集合
  10. Erp第二章:业务流程化、集成、规划
  11. Python转码问题的解决方法:ignore,replace,xmlcharrefreplace
  12. 【ThinkingInC++】61、非成员运算符
  13. 离线缓存 manifest
  14. NoSQL性能测试工具YCSB-Running a Workload
  15. IOS开发中关于runtime的认识
  16. sql server存储过程,常用的格式
  17. 关于form与表单操作
  18. Vistual Studio Community 2017 账号的许可证过期,公安网激活方法
  19. 拼接html a标签字符串,onClick传递两个字符串类型参数写法
  20. 2018-2019-2 《网络对抗技术》Exp5 MSF基础应用 Week7-8 20165233

热门文章

  1. nginx的跨域设置
  2. (5)打造简单OS-进入保护模式
  3. centos6和centos7中常用命令区别
  4. HearthBuddy 调试肯瑞托法师寒冰屏障的配合
  5. 【转】nodejs获取post请求发送的formData数据
  6. IOS和Andriod手机浏览器内核
  7. Android:Mstar Android8.0平台音量控制流程
  8. final和finally和finalize的区别
  9. Linux给力的Shell命令
  10. Tomcat监听shutdown释放数据库连接池