力扣494 目标和

题目:

给你一个整数数组nums和一个整数target 。
向数组中的每个整数前添加'+'或'-',然后串联起所有整数,可以构造一个表达式 :
    例如,nums=[2, 1],可以在 2 之前添加'+',在1之前添加'-',然后串联起来得到表达式"+2-1"。
返回可以通过上述方法构造的、运算结果等于target的不同表达式的数目。

示例:

输入:nums = [1,1,1,1,1], target = 3
输出:5
解释:一共有 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

思路:

  本题要如何使表达式结果为target,设加法组合为left,减法组合为right。则(1)left+right=sum (2)left-right=target,注意这里的right指的是减法组合,并不是带着减号的数,所以有left-right=target

已经有一个1(nums[i]) 的话,有 dp[4]种方法 凑成 容量为5的背包。
已经有一个2(nums[i]) 的话,有 dp[3]种方法 凑成 容量为5的背包。
已经有一个3(nums[i]) 的话,有 dp[2]中方法 凑成 容量为5的背包
已经有一个4(nums[i]) 的话,有 dp[1]中方法 凑成 容量为5的背包
已经有一个5 (nums[i])的话,有 dp[0]中方法 凑成 容量为5的背包

  确定递推公式环节:
        求组合类的问题都是类似于这种,其实就是把这些方法加起来就可以了。
        几乎所有的背包解决排列组合问题,都是用这个递推公式
        记住:在求装满背包有几种方法的情况下,递推公式就是这个:
        dp[j] = dp[j] + dp[j - nums[i]]

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum=0;
        for (int i=0;i<nums.length;i++){
            sum+=nums[i];
        }
        //如果target过大 sum将无法满足
        if (target<0 && sum<-target) 
            return 0;
        if ((target+sum)%2!=0) 
            return 0;

        int size=(target+sum)/2;//left集合的大小
        if(size<0) 
            size=-size;
        //1.dp定义:dp[j]表示:填满j(包括j)这么大容积的包,有dp[j]种方法
        int[] dp=new int[size+1];
        //2.初始化
        dp[0] = 1;
        //3.递推公式
        //4.遍历顺序
        for (int i=0;i<nums.length;i++) {
            for (int j=size;j>=nums[i];j--) {
                dp[j]+=dp[j-nums[i]];
            }
        }
        return dp[size];
    }
}

 

posted @ 2023-03-01 14:56  壹索007  阅读(6)  评论(0编辑  收藏  举报