My Seventy-first Page - 目标和 - By Nicolas

这篇page是针对leetcode上的494.目标和所写的。小尼先简单的说明一下这道题的意思,就是给出一个整数数组nums和一个整数target,需要向数组中的每个整数前添加'+'或者'-',然后串联起所有整数,可以构造一个表达式,返回可以通过上述方法构造的、运算结果等于target的不同表达式的数目。

首先呢小尼先简单的说明一下这道题的解题思路,我们不要把这道题想的过于复杂,也不要将这道题想的过于简单,其实这里可以写+也可以写-,其实无非就是构造成正数或者是负数,其实就是我们构造两个数组进行对应的赋值即可,一个数组里面全部都是赋值正数,另一个里面全部都是赋值负数。我们如果将所有的正数数组都定义为left,所有的负数数组都定义为right,那么我们定义一个sum=left+right,left-(sum-left)=target,那么我们通过上述三个式子我们可以推出一个结论就是,left=(target+sum)/2,然后我们需要的是满足为target的组合,其实就直接转换成了0-1背包问题,装满容器为x背包,有几种方法。

小尼接下来继续说明一下动态规划五部曲:

1、确定dp数组以及下标的含义:dp[j]表示:填满j(包括j)这么大容积的包,有dp[j]种方法

2、确定递推公式:当我们考虑到nums[i]的话,凑成dp[j]就有dp[j]-nums[i]种方法,这里其实就是类似于一个累加起来的方法

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

3、dp数组如何进行初始化:从递归公式我们可以看出,在初始化的时候dp[0]一定要初始化为1,因为dp[0]是在公式种一切递推结果的起源,所以dp[0]一定只能是1,如果为0,那么之后的所有的结果都将是0

4、确定遍历顺序:跟我们之前说过的0-1背包问题一样,nums放在外循环,target在内循环,且内循环倒序

5、最后就是导出dp数组

小尼接下来拉一下解题代码:

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        for(int i = 0; i < nums.length; i++) sum += nums[i];
        if((target + sum) % 2 != 0) return 0;
        int size = (target + sum) / 2;
        if(size < 0) size = - size;
        int[] dp = new int[size + 1];
        dp[0] = 1;
        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];
    }
}

小尼简单的即使一下上述的代码,其中有一个可以很直接判断的条件,就是如果(target+sum)%2如果不为0,那么我们直接return false,其实这里如果不为0就是我们题目的条件给不出返回结果是算出的数的背包,其实就是我们不能组成的,然后接下来我们直接就是进行对应对遍历,我们需要返回可以达到的方法数,最后我们直接返回dp[size]。我们在这道题中先遍历的是物品,然后再遍历的是背包的容量,其实就是我们一个个记录的操作,我们先放入第一个物品,然后我们记录好dp数组,接下来我们继续放入之后的物品,然后我们的dp数组根据之前已经叠加了的数据进行对应的继续增加,最后再返回我们的dp[size]的值

希望上述代码可以帮助到小伙伴们~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值