原题链接在这里:https://leetcode.com/problems/target-sum/description/

题目:

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.

题解:

List some examples. e.g. 1,1,1,1,1.

If all of them are positive, it is 5, all negitative, it is -5. Beyond [-5,5], it can't happen, thus, the ways count is 0.

For this sum question, let dp[i] denotes the sum up to i, the count of ways.

Iterate each num in nums. For num, it could be + or -. say first 1. Then it could -1 or 1.

The ways to -1 is 1, ways to 1 is 1. It is because dp[0] accumlate to dp[1] and dp[-1].

递推时, 上个可能结果或加或减当前num得到新的结果, 不同ways的数目在新结果下累计.  只有对应count大于0时才可能是上个可能结果, because it would not be out of index.

起始值dp[0 + sum] = 1. 可能结果为0的不同ways数目是1. sum is offset. dp[0] means sum up to -sum.

Time Complexity: O(sum * n). sum是nums所有num的和. n = nums.length

Space: O(sum).

AC Java:

 class Solution {
public int findTargetSumWays(int[] nums, int S) {
if(nums == null || nums.length == 0){
return 0;
} int sum = 0;
for(int num : nums){
sum += num;
} if(sum < S || -sum > S){
return 0;
} int [] dp = new int[2*sum+1];
//sum相当于 offset
dp[0+sum] = 1;
for(int num : nums){
int [] next = new int[2*sum+1];
for(int k = 0; k<2*sum+1; k++){
if(dp[k] > 0){
next[k+num] += dp[k];
next[k-num] += dp[k];
}
}
dp = next;
}
return dp[sum + S];
}
}

Method 2:

nums中一部分用的+号 相当于positive, 另一部分用的 - 号相当于negative. 分成两组.

sum(p) - sum(n) = target.

sum(p) + sum(n) + sum(p)-sum(n) = target + sum(p) + sum(n)

2*sum(p) = target + sum(nums)

相当于在nums中找有多少种subarray, subarray自身的和是(target + sum(nums))/2的问题.

subSum求解这个转化问题.

存储到当前数字得到所有结果ways数目. 为什么循环中i要从大到小呢. 这其实是dp的space compression.

update新的dp时会用到上一轮前面的值,所以要从后往前更新. 这样更新时保证用到的都是上轮的值.

Time Complexity: O(sum*nums.length). sum是nums所有num的和.

Space: O(sum).

AC Java:

class Solution {
public int findTargetSumWays(int[] nums, int S) {
int sum = 0;
for(int num : nums){
sum += num;
} if(S < -sum || S > sum || (S+sum)%2 != 0){
return 0;
} return subSum(nums, (S+sum)/2);
} private int subSum(int [] nums, int target){
int [] dp = new int[target+1];
dp[0] = 1;
for(int num : nums){
for(int i = target; i>=num; i--){
dp[i] += dp[i-num];
}
} return dp[target];
}
}

类似Partition Equal Subset Sum.

LeetCode Target Sum的更多相关文章

  1. [LeetCode] Target Sum 目标和

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

  2. Leetcode——Target Sum

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

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

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

  4. [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 ...

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

  6. Longest subarray of target sum

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

  7. LeetCode:Path Sum I II

    LeetCode:Path Sum Given a binary tree and a sum, determine if the tree has a root-to-leaf path such ...

  8. [leetcode] Combination Sum and Combination SumII

    Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C wher ...

  9. 剑指offer 65. 不用加减乘除做加法(Leetcode 371. Sum of Two Integers)

    剑指offer 65. 不用加减乘除做加法(Leetcode 371. Sum of Two Integers) https://leetcode.com/problems/sum-of-two-in ...

随机推荐

  1. java FileUtils 文件工具类

    package com.sicdt.library.core.utils; import java.io.BufferedInputStream; import java.io.File; impor ...

  2. [转]AOP那些学术概念—通知、增强处理连接点(JoinPoint)切面(Aspect)

    AOP那些学术概念—通知.增强处理连接点(JoinPoint)切面(Aspect) 1.我所知道的AOP 初看起来,上来就是一大堆的术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充 ...

  3. Eclipse Class Decompiler——Java反编译插件

    http://www.blogjava.net/cnfree/archive/2012/10/30/390457.html Eclipse Class Decompiler是一款Eclipse插件,整 ...

  4. Linux 调优

    一.系统优化 1.硬件优化 增加内存 更换速度跟高磁盘(sata->sas)可以增加固态硬盘 更换更高校率的网卡,或者双网卡绑定,两个网卡作为一个网卡使用.服务器网卡一般为千兆 2.系统层优化 ...

  5. Linux的压缩命令(tar,gzip,zip)

    打包和压缩.打包是指将一大堆文件或目录变成一个总的文件:压缩则是将一个大的文件通过一些压缩算法变成一个小文件. 这源于Linux中很多压缩程序只能针对一个文件进行压缩,这样当你想要压缩一大堆文件时,你 ...

  6. php数组函数-array_rand()

    array_rand()函数返回数组中的一个随机键名,或者如果指定函数返回键名不止一个,则返 回一个包含随机键名的数组. array_rand(array,number); array:必需.规定数组 ...

  7. 优美的英文诗歌Beautiful English Poetry

    <When you are old>——<当你老了> --- William Butler Yeats ——威廉·巴特勒·叶芝When you are old and grey ...

  8. Eclipse开发快捷键精选

    1.alt+?或alt+/:自动补全代码或者提示代码2.ctrl+o:快速outline视图3.ctrl+shift+r:打开资源列表4.ctrl+shift+f:格式化代码5.ctrl+e:快速转换 ...

  9. 10个超有趣的linux命令

    本文展示了 10 个有趣的 Linux 动态命令,这些命令和实用功能无关,仅供娱乐!看完此文,你会对 Linux 有个全新的认识,谁说 IT 男就没有屌丝娱乐的一面呢?还等什么,就让我们开始看文章吧~ ...

  10. springcloud一些概念知识

    1.Eureka 1)Eureka服务治理体系支持跨平台 2)三个核心概念:服务注册中心.服务提供者以及服务消费者 3)服务续约:注册完服务之后,服务提供者会维护一个心跳来不停的告诉Eureka Se ...