LeetCode494 目标和

该博客介绍了如何利用动态规划解决一个看似是回溯遍历,实则是0-1背包问题的算法。文章通过分析得出目标和与数组总和的关系,提出当总和与目标和不能被2整除时无解,并给出动态规划的解决方案。通过遍历数组并更新动态规划数组,找到填满目标和的一半(即左值)的填充方案数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:494. 目标和 - 力扣(Leetcode)

思路:看似是回溯遍历问题,其实是0-1背包问题,使用动态规划解决最好。

加法总和x,那么减法总和为sum-x。

x-(sum-x) =target,也就可以推出x=(sum+target)/2

public class FindTargetSumWays {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        // 求出数组的总和
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        // 不能被整除的话,方法是无解的,例如sum=5,target=2
        if ((target+sum)%2!=0){
            return 0;
        }
        /***
         * 推导步骤:
         * step1: left+right = sum
         * step2: left-right = target
         * step3: left = (sum+target)/2 此时就将这个问题转换为填充满left(x)有几种填充方案,也就是变成了一个0-1背包问题了
         */
        int size = (target+sum)/2;
        // 为了便于后续计算,将负的size转换为正的
        if (size<0){
            size=-size;
        }
        int[] dp = new int[size+1]; // step1:次数数组的含义是:填满j这么大的背包,dp[j]有几种解法
        // 初始化,也就是装载容量为0的背包,有一种方法,就是啥也不装
        dp[0] = 1;
        /**
         * 使用动态数组解0-1背包问题,注意点:j从后往前遍历且能取到nums[i]
         * */
        for (int i = 0; i < nums.length; i++) {
            for (int j = size; j >= nums[i]; j--) {
                // step2:确定递归公式
                dp[j] += dp[j-nums[i]];
            }
        }
        return dp[size];
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值