Leetcode-494-Target-Sum

Leetcode-494-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:

 

1

2

3

4

5

6

7

8

9

10

 

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

题目大意

给定一个正数数组以及一个整数S,现在有两个符号+-,对于数组里面的每一个数字,你可以选择+或者-作为它的新符号,找出所有选择符号的方式,使这些数字和为S。简单来说,给定一个数组,每个数可以加或者减,求出所有能使这些数字加减和为S的组合数。如{1,1,1,1,1},S为3,那么一共有5种方法使得这些数字和为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
+1+1+1+1-1 = 3

思路

假设数组中所有数字之和为sum。根据使用的符号不同,我们可以将数组内数字分为2组PN,如数组{1,2,3},目标为0,那么显然有如下选择方式:

+1+2-3 = 0

那么其中P={1,2},N={3}。那么sum(P)-sum(N)=S,并且sum(P)+sum(N)=sum。由此可以推出S+sum=sum(P)-sum(N)+sum(P)+sum(N)=2*sum(P)

这样我们就把原来的问题转换成了一个新的问题,在整个数组中,能否找到一些数字的和为(S+sum)/2,这就成了一个最经典的0-1背包问题,这样的话就简单了很多。

这里有一个需要注意的地方,(S+sum)/2这个数必须为偶数,否则无法得到,其次,S也必须小于sum,否则也无法求得。

这个算法的空间复杂度不定,取决于Ssum,不过题目限制了sum < 1000,那么空间复杂度为O(sum)。至于时间复杂度也取决于sum,时间复杂度是O(sum*N2)。Java版的代码如下:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 

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

int sum = 0;

for (int i = 0; i < nums.length; i ++){

sum += nums[i];

}

if (S > sum || (S + sum) % 2 != 0){

return 0;

}

sum = (S + sum) / 2;

int [] dp = new int[sum + 1];

dp[0] = 1;

for (int i = 0; i < nums.length; i ++){

for (int j = sum; j >= nums[i]; j --){

dp[j] += dp[j - nums[i]];

}

}

return dp[sum];

}

提交结果如下:

运行结果

运行结果

 

总结

最近在刷Leetcode上的tag为动态规划的题,做了那么多其实动态规划的思想一直没变,最重要的是找到状态、状态转移公式以及转移状态的条件。当然,有的时候还需要一些数学推导,把当前不熟悉的问题转化成熟悉的问题。
```
原文链接:http://KingsFish.github.io/2017/08/22/Leetcode-494-Target-Sum/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值