Skip to content

服务器托管,北京服务器托管,服务器租用-价格及机房咨询

Menu
  • 首页
  • 关于我们
  • 新闻资讯
  • 数据中心
  • 服务器托管
  • 服务器租用
  • 机房租用
  • 支持中心
  • 解决方案
  • 联系我们
Menu

LeetCode – 494 目标和

Posted on 2023年5月6日 by hackdl

目录

题目来源

题目描述

示例

提示

题目解析

算法源码


题目来源

494. 目标和 – 力扣(LeetCode)

题目描述

给你一个整数数组 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
输入 nums = [1], target = 1
输出 1
解释 无

提示

  • 1
  • 0
  • 0
  • -1000

题目解析

题目中说:

向数组中的每个整数前添加 ‘+’ 或 ‘-‘ ,然后串联起所有整数,可以构造一个 表达式

其实可以理解为将数组中的数分为两类:+号的一类positive,-号的一类negative,因此可得公式如下:

  • positive + negative = sum(nums)
  • positive – negative = target

根据上面公式可得: positive = (sum(nums) + target) / 2

而sum(nums)、target都是给定的值,因此本题可以转化为,从nums数组中选出任意个数,只要选出的数之和为 (sum(nums) + target) / 2 即可。

由于本题中所有数都是整数,因此选出任意个数的和也一定是整数,如果(sum(nums) + target) / 2结果不是整数,则说明无法选出对应组合,此时应该返回0。

如果(sum(nums) + target) / 2的结果是整数,那么本题其实就可以转化为01背包问题:

有nums种物品,每种物品只有一个,每种物品的重量是nums[i],有一个背包,背包承重是(sum(nums) + target) / 2,现在问有多少种装满背包的方式?

可以发现,上面的求解还是有别于一般的01背包问题的,一般的01背包问题是:

有N种物品,每种物品只有一个,每种物品的重量为w[i],价值为p[i],有一个背包,背包承重是W,问背包装入物品的最大价值是多少?

其实上面两个问题都是01背包问题,01背包问题通常有三类:

  • 背包能装入物品的最大价值
  • 背包是否可以装满
  • 背包装满有多少种方式

本题属于01背包的第三种问题,即背包装满有多少种方式。

我们假设 dp[i][j] 表示:”从0 ~ i 物品中选择任意物品,能够装满容量 j 的背包 “ 的装满背包的方案的个数。

那么按照01背包的思维,第 i 个物品我们可以选择装入或者不装入,那么:

  • 第 i 个物品我选择装入的话,那么此时dp[i][j]有多少种?
  • 第 i 个物品我们选择不装入的话,那么此时dp[i][j]又有多少种?

如果第 i 个物品不装入,那么dp[i][j]装满背包的方案数其实就等价于dp[i-1][j]装满背包的方案数,即此时:dp[i][j] = dp[i-1][j]

举个例子:

你有三件物品,重量分别为2,3,5,你有一个背包,承重为5,那么现在有两种方式装满背包:

  • 装入2,3
  • 装入5

然后又新增了一个物品,重量为x,但是目前这个x已经确定不装入背包了,那么这四件物品2,3,5,x,能够装满背包5的方案数其实还是两种。

如果第 i 个物品装入,那么dp[i][j] 装满背包的方案数其实就等价于 dp[i-1][j – nums[i]] 装满背包的方案数,即此时:dp[i][j] = dp[i-1][j – nums[i]]

举个例子:

你有三件物品,重量分别为2,3,5,你有一个背包,承重为5,那么现在有两种方式装满背包:

  • 装入2,3
  • 装入5

然后又新增了一个物品,重量为x,并且背包的承重也增加了x(背包承重从 j – nums[i] 变为了 j ),此时依旧只有两种装满背包的方案:

  • 装入2,3,x
  • 装入5,x

由于我们求得是装满背包的方案数,而不是最大价值,因此这里我们不需要Math.max去取最大,而是直接求和:

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

当然,如果物品nums[i]重量超过了 j 背包承重,即 j – nums[i]

dp[i][j]  =  dp[i-1][j]

最后本题还有一个问题,那就是dp[0][0]应该初始化为多少?

这里直接给出答案:dp[0][0] = 1

可能有人会产生疑问,【从0 ~ 0 物品中选择任意物品,能够装满容量 0 的背包】的方案数有1种?难道不是0种吗?

其实我觉得0种也是符合认知的,但是在这里却不符合代码逻辑,假设dp[0][0] = 0,那么dp[1][1]等于多少呢?

根据前面的状态转义公式,此时dp[1][1] = 0,但是实际上

【从0 ~ 1 物品中选择任意物品,能够装满容量 1 的背包】的方案数是有可能为1种的。因此本题dp[0][0]需要初始化为1。

Java算法源码

01背包二维数组解法

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        for(int num : nums) sum += num;
        if((sum + target) % 2 != 0) return 0;

        int bag = (sum + target) / 2;
        if(bag 

01背包滚动数组优化

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        for(int num : nums) sum += num;
        if((sum + target) % 2 != 0) return 0;

        int bag = (sum + target) / 2;
        if(bag =num; j--) {
                dp[j] = dp[j] + dp[j-num];
            }
        }

        return dp[bag];
    }
}

 

JS算法源码

01背包二维数组解法

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var findTargetSumWays = function(nums, target) {
    const sum = nums.reduce((a,b) => a + b);
    if((sum + target) % 2 != 0) return 0;

    const bag = (sum + target) / 2;
    if(bag  new Array(bag+1).fill(0));
    dp[0][0] = 1;

    for(let i=1; i

 

01背包滚动数组优化

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var findTargetSumWays = function(nums, target) {
    let sum = 0;
    for(let num of nums) sum += num;
    if((sum + target) % 2 != 0) return 0;

    const bag = (sum + target) / 2;
    if(bag =num; j--) {
            dp[j] = dp[j] + dp[j - num];
        }
    }

    return dp.at(-1);
};

 

Python算法源码

01背包二维数组解法

class Solution(object):
    def findTargetSumWays(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        total = sum(nums)

        if (total + target) % 2 != 0:
            return 0
        
        bag = (total + target) // 2

        if bag 

01背包滚动数组优化

class Solution(object):
    def findTargetSumWays(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        total = sum(nums)

        if (total + target) % 2 != 0:
            return 0
        
        bag = (total + target) // 2

        if bag 

服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net

Related posts:

  1. 北京服务器托管机房云服务器
  2. 重庆服务器托管品牌质量对比:选哪个?
  3. 企业租用机柜注意事项
  4. 广东虚拟服务器托管机构:高效稳定的互联网服务提供商
  5. 最近找工作时,一些杂七杂八的问题

服务器托管,北京服务器托管,服务器租用,机房机柜带宽租用

服务器托管

咨询:董先生

电话13051898268 QQ/微信93663045!

上一篇: Spring Cloud Alibaba全家桶——微服务链路追踪SkyWalking 前言 目录 一、SkyWalking简介 二、SkyWalking环境搭建部署 三、SkyWalking接入微服务 四、SkyWalking持久化跟踪数据
下一篇: 如何对市场进行深入了解,了解当前市场上的热销产品、消费者需求以及行业发展趋势?在哪里寻找专业报告、行业数据、市场分析文章等?

最新更新

  • 五月学习之keepalived 软件简介
  • Cibersort免疫浸润的在线分析及R语言代码实现
  • 阿里云的认证最有几个等级?考试费用是多少?
  • 京东APP百亿级商品与车关系数据检索实践 | 京东云技术团队
  • 【Hello Network】TCP协议 TCP协议 确认应答机制 (ACK) 超时重传机制 连接管理机制 流量控制 滑动窗口 拥塞控制 延时应答 捎带应答 面向字节流 粘包问题 TCP的异常情况 TCP小结 基于TCP的应用层协议

随机推荐

  • 桂林服务器托管公司排名及推荐
  • 【MyBiatis框架】Jdbc的弊端探讨和MyB
  • Apache hudi 核心功能点分析
  • 机柜租用方案
  • 稳定可靠的CentOS FTP服务器托管服务

客服咨询

  • 董先生
  • 微信/QQ:93663045
  • 电话:13051898268
  • 邮箱:dongli@hhisp.com
  • 地址:北京市石景山区重聚园甲18号2层

友情链接

  • 服务器托管
  • 服务器租用
  • 机房租用托管
  • 服务器租用托管
©2023 服务器托管,北京服务器托管,服务器租用-价格及机房咨询 京ICP备13047091号-8