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:

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.

题意:给出一串数字数组nums[ ]和一个目标和S,求有多少种组合方式能在每个数前添加‘ + ’或‘ - ’ ,使最后的和等于目标和S。

思路:从网上学到的解题思路如下:

将数组分成正数和负数两个子数组,分别命名P[ ]和N[ ],正数的和为sum(P),负数的和sum(N),

根据推算可得出以下结论:

                                  sum(P) - sum(N) = target

sum(P) + sum(N) + sum(P) - sum(N) = target + sum(P) + sum(N)

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

因此将解题思路转变为数组中的部分数字有多少种方式组合得到 sum(P) ,变成背包问题。

因此,sum(P)能被组合的数量 = sum(P)-num 能被组合的累加和,(num是nums数组中的每一个数)

代码:

class Solution {
    public int findTargetSumWays(int[] nums, int S) {
        int sum=S;
        for(int n : nums){
            sum+=n;
        }
        //如果数组和+目标数的和为奇数时 或 数组和小于目标和时 ,肯定不能被组合  
        if(sum%2 == 1 || sum<2*S) 
            return 0;
        sum /= 2;
        int[] dp = new int[sum+1];
        dp[0] = 1;
        
        for(int n: nums){
            for(int i=sum;i>=n;i--){
                dp[i] += dp[i-n];
            }
        }
        return dp[sum];
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值