494. Target Sum

一、题目

  1、审题 

  

  

  2、分析

    给出一个正整数数组。为每个元素添加 + 、- 符号,然后将元素相加,求共有多少种组合使得和为  S;

 

二、解答

  方法一、

    ① 将此问题转化为取数组中若干元素,使得元素和为某一定值的问题:

    假设正数集合为 P, 负数集合为 N;则有:

      sum[P] - sum[N] = S

      sum[P] + sum[N] + sum[P] - sum[N] = S + sum[nums]

    即:

      sum[P] = (S + sum[nums]) / 2

 

    ② 求若干元素和为特定值解法为:  https://www.cnblogs.com/skillking/p/10948836.html

    ③ 采用一维整形动态数组: dp[s + 1]。 其中 dp[i]: 表示数组 nums 中元素随意组合和 为 i 的组合个数。

    ④ 最终返回 dp[s]

   public int findTargetSumWays(int[] nums, int s) {
        int sum = 0;
        for(int n : nums) 
            sum += n;
        
        if(sum < s || (s + sum) % 2 == 1)
            return 0;

        return subsetSum(nums, (s + sum) >>> 1);
    }
    
    private int subsetSum(int[] nums, int s) {
        int[] dp = new int[s + 1];
        dp[0] = 1;    // 在 nums 中取若干个元素求和,和为 0 的组合共 1 个
        for(int n: nums) {
            for (int i = s; i >= n; i--) {
                dp[i] += dp[i - n];
            }
        }
        return dp[s];
    }

 

 
posted @ 2019-05-30 21:18  skillking2  阅读(47)  评论(0编辑  收藏