目标和-动态规划

目标和——动态规划 给定一个整数数组`nums` 和一个整数 `target`,向数组中的每个整数前添加`'+'`或`'-'`,然后串联起所有整数,使得他们的相加和等于target`,返回符合上诉构造方法,且运算结果等于`target`的不同表达式的数目。 阅读详情

给你一个整数数组 nums 和一个整数 target 。

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

例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串联起来得到表达式 “+2-1” 。
返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

示例 1:

输入: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
示例 2:

输入:nums = [1], target = 1
输出:1

提示:

1 <= nums.length <= 20
0 <= nums[i] <= 1000
0 <= sum(nums[i]) <= 1000
-1000 <= target <= 1000

转:https://leetcode.cn/problems/target-sum/solution/mu-biao-he-by-leetcode-solution-o0cp/

动态规划

记数组的元素和为 sumsumsum,添加 −-− 号的元素之和为 negnegneg,则其余添加 +++ 的元素之和为 sum−negsum−negsum−neg,得到的表达式的结果为

(sum−neg)−neg=sum−2∗neg=target(sum-neg) - neg = sum - 2*neg=target(sum−neg)−neg=sum−2∗neg=target

即

neg=sum−target2neg = \frac{sum-target}{2}neg=2sum−target​

由于数组 numsnumsnums 中的元素都是非负整数,negnegneg 也必须是非负整数,所以上式成立的前提是 sum−targetsum−targetsum−target 是非负偶数。若不符合该条件可直接返回 0。

若上式成立,问题转化成在数组 numsnumsnums 中选取若干元素,使得这些元素之和等于 negnegneg,计算选取元素的方案数。我们可以使用动态规划的方法求解。

定义二维数组 dpdpdp,其中 dp[i][j]dp[i][j]dp[i][j] 表示在数组 numsnumsnums 的前 iii 个数中选取元素,使得这些元素之和等于 jjj 的方案数。假设数组 numsnumsnums 的长度为 nnn,则最终答案为 dp[n][neg]dp[n][neg]dp[n][neg]。

当没有任何元素可以选取时,元素和只能是 0,对应的方案数是 1,因此动态规划的边界条件是:

dp[0][j]={1,j=00,j>=1dp[0][j]=\begin{cases} 1, j=0\\ 0, j >=1\end{cases}dp[0][j]={1,j=00,j>=1​

当 1≤i≤n1≤i≤n1≤i≤n 时,对于数组 numsnumsnums 中的第 i 个元素 numnumnum(i 的计数从 1 开始),遍历 0≤j≤neg0≤j≤neg0≤j≤neg,计算 dp[i][j]dp[i][j]dp[i][j] 的值:

如果 j<numj<numj<num,则不能选 numnumnum,此时有 dp[i][j]=dp[i−1][j]dp[i][j]=dp[i-1][j]dp[i][j]=dp[i−1][j];

如果 j≥numj≥numj≥num,则如果不选 numnumnum,方案数是 dp[i−1][j]dp[i-1][j]dp[i−1][j],如果选 numnumnum,方案数是 dp[i−1][j−num]dp[i-1][j−num]dp[i−1][j−num],此时有 dp[i][j]=dp[i−1][j]+dp[i−1][j−num]dp[i][j]=dp[i-1][j]+dp[i-1][j−num]dp[i][j]=dp[i−1][j]+dp[i−1][j−num]

因此状态转移方程如下:

dp[i][j]={dp[i−1][j],j<numsdp[i−1][j]+dp[i−1][j−num],j>=numsdp[i][j]=\begin{cases} dp[i-1][j], j<nums \\ dp[i-1][j]+dp[i-1][j−num], j >=nums\end{cases}dp[i][j]={dp[i−1][j],j<numsdp[i−1][j]+dp[i−1][j−num],j>=nums​

最终得到 dp[n][neg]dp[n][neg]dp[n][neg] 的值即为答案。

由此可以得到空间复杂度为 O(n×neg)O(n×neg)O(n×neg) 的实现.

class Solution:
    def findTargetSumWays(self, nums: list, target: int) -> int:
        sums = sum(nums)

        diff = sums - target
        if diff < 0 or diff % 2 != 0:
            return 0

        n = len(nums)
        neg = diff // 2
        dp = [[0] * (neg + 1) for i in range(n+1)]
        dp[0][0] = 1
        for i in range(1, n+1):
            num = nums[i-1]
            for j in range(neg + 1):
                dp[i][j] = dp[i -1][j]
                if j >= num:
                    dp[i][j] += dp[i-1][j-num]

        return dp[n][neg]


if __name__ == '__main__':
    s = Solution()
    print(s.findTargetSumWays([1,1,1,1,1], 3))

复杂度分析

时间复杂度:O(n×(sum−target))O(n \times (\textit{sum}-\textit{target}))O(n×(sum−target)),其中 n 是数组 nums 的长度,sum 是数组 nums 的元素和,target 是目标数。动态规划有$ (n+1) \times (\dfrac{\textit{sum}-\textit{target}}{2}+1)$ 个状态,需要计算每个状态的值。

空间复杂度:O(sum−target)O(\textit{sum}-\textit{target})O(sum−target),其中 sum 是数组 nums 的元素和,target 是目标数。使用空间优化的实现,需要创建长度为 sum−target2+1\dfrac{\textit{sum}-\textit{target}}{2}+12sum−target​+1的数组 dp。

动态规划+双向扩散 494. 目标和 给定一个非负整数数组,a1, a2, …, an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。 返回可以使最终数组和为目标数 S 的所有添加符号的方法数。 示例 1: 输入: nums: [1, 1, 1, 1, 1], S: 3 输出: 5 解释: -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 一共有5种方法让最终目标 阅读详情

相关推荐

从FinFET到NanoSheet:一文看懂TSMC制程技术的架构革命与性能飞跃

本文深入解析了TSMC从FinFET到NanoSheet的制程技术架构革命。FinFET通过三维立体结构解决了短沟道效应,而NanoSheet采用环绕栅极设计,实现了更强的静电控制与设计灵活性,结合EUV光刻技术,共同推动了芯片性能与能效的飞跃,为下一代AI与高性能计算奠定基石。

i3j4k5的博客 291

动态规划之-目标和(target sum)

目标和 动态规划 回溯

Jasonchen1224的博客 1244

MatLab:数字图像处理实验

图像处理基本处理实验目的实验环境实验内容题目一代码结果题目二平移平移代码平移结果水平镜像水平镜像代码水平镜像结果垂直镜像垂直镜像代码垂直镜像结果放大放大代码放大结果缩小缩小代码缩小结果旋转旋转代码旋转结果双线性旋转旋转代码旋转结果 实验目的 1、熟悉并掌握MATLAB工具的使用;  2、实现图像的读取、显示、存储、平移、镜像、放大、缩小及旋转操作; 3、掌握常用的插值方法,并了解其优缺点。 实验环境 MatLab2016 实验内容 题目一 读入一幅RGB图像,变换为灰度图像和二值图像,并在同一个窗口内分别显

luoyao_的博客 9696

力扣494.目标和(动态规划)

推导题意:本题是将数组分为两组,一组是加号,另一组是减号 设加数为x,减数为y: x + y = sum; x - y = target; 而数组总和可以自己求出来,数组target题目已给,所以可以推出x的值: x = (sum +target)/2; 如果后者能除尽则可以用加减号计算出结果,若除有余数则不可能计算出target 所以本题转化为动态规划背包问题 设一维dp滚动...

qq_57205114的博客 391

Doris + Iceberg 实现高效数据湖分层:架构解析与最佳实践

本文深入解析了如何利用Doris与Iceberg构建高效的数据湖冷热分层架构。通过将高频访问的热数据存储在Doris中以实现毫秒级查询,同时将历史冷数据归档至低成本的Iceberg存储,该方案在保障查询性能的同时显著降低了总体拥有成本。文章详细阐述了从架构设计、自动化迁移到统一查询的最佳实践,为应对海量数据下的成本与性能平衡提供了实战指南。

weixin_29207533的博客 135

Ollama-OCR实战:5分钟搞定PDF文档转Markdown(附qwen2.5vl模型配置)

本文详细介绍了如何利用Ollama本地部署多模态大模型qwen2.5vl,结合OCR技术,实现PDF文档到Markdown的端到端智能转换。通过解析传统OCR的局限与AI方案的优势,并提供从环境搭建、提示词工程到处理复杂表格的完整实战指南,帮助用户高效构建自动化文档处理流水线,彻底重塑文档处理工作流。

yog99的博客 606

动态规划4:目标和、一和零、完全背包理论、零钱兑换||、第4节总结

目标和难点是想到背包的容量是left,因为sum和target固定,所以left=(sum+target)/2。并且还要想到sum和target同奇同偶可以剪枝。所以,题目就转换为了在容量为left的背包中,和为left的组合数。一和零一个字符串数组中的每个字符串的1、0个数,找到满足m个0,n个1的最长子集数。dp[i][j]表示满足(小于等于)i个0和j个1的字符串个数。dp[i][j]应该由去掉当前字符串的01个数后的个数+1,与本身的最大值决定。

evildoerxmf的博客 252

CorelDRAW 2019安装指南:从下载到激活的完整步骤

本文提供了一份详细的CorelDRAW 2019安装指南,涵盖从下载安装包、检查系统环境到完成激活的完整步骤。文章重点解析了安装过程中的关键选项设置,并分享了首次启动后的优化配置与常见问题解决方案,旨在帮助用户高效、顺利地完成这款经典矢量设计软件的安装与配置。

weixin_29213827的博客 839

2021-12-6 494. 目标和(动态规划)

注: 题目: 给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘+’ 或 ‘-’ ,然后串联起所有整数,可以构造一个 表达式 : 例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串联起来得到表达式 “+2-1” 。 返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。 示例 1: 输入:nums = [1,1,1,1,1], target = 3 输出:5 解释:一共有 5 种方法让最终目标和

TABE_的博客 469

【YOLOv10[基础]】热力图可视化实践③ | 热力图脚本升级 | 优化可视化效果 | 论文必备 | GradCAMPlusPlus, GradCAM, XGradCAM, EigenCAM等

热力图可视化实践③ | 热力图脚本升级 | 优化可视化效果 | 论文必备 | 遥遥领先

静谧、淡雅 3222

AI智能体面试实战与真题解析: 312+道面试题完整答案 (下篇)

本文覆盖220道基础八股文+92道项目面试题,涵盖Agent架构、RAG、工具调用、记忆系统、多智能体、大模型基础、工程化实践、Prompt工程9大模块,含完整代码实现和模拟面试剧本。

program哲学 303

力扣LeetCode:494. 目标和(动态规划)

原有的 dp【i-1】【j】加上新增的dp【i-1】[j-nums【i】], 就可以得到所求的dp【i】【j】如果选第i个元素,那么剩下要组成和为j - nums【i】 的方案数就等于dp[j - nums【i】]递推公式一般为:dp【i】【j】 = dp【i-1】【j】 + dp【i-1】[j-nums【i】]递推公式一般为:dp[j] += dp[j - nums[i]];那么有两种选择:不选第i个元素或者选第i个元素。二维DP数组求装满背包有几种方法的情况下。,然后串联起所有整数,可以构造一个。

欢迎访问我的个人Blog网站:blog.homeryland.org 194

Office系列完全干净卸载工具合集(最全)

使用 Microsoft Fix it 卸载 Microsoft Office 套件 一、Windows 7、Windows Vista或Windows XP下卸载Office 1.MicrosoftEasyFix50416 工具用来卸载office 2003 MicrosoftEasyFix50416_Office2003.msi 2.MicrosoftEasyFix50154 工具用来卸载office 2007 MicrosoftEasyFix50154_Office2007.msi 3.Microso

业精于勤,荒于嬉 3万+

动态规划LeetCode-494.目标和

那我们可以把dp[j]的含义表示为装满容量为j有dp[j]种方法。那第二求的背包容量是多少呢?这里是用一维滚动数组来解决,所以物品遍历的for循环放在外层,遍历背包的for循环放在内层,然后题目说物品i只能放一次,所以且内层for循环倒序遍历!dp[j] = dp[j] + dp[j - nums[i]] # 即 dp[j] += dp[j - nums[i]]01背包排列组合问题的递推公式为:dp[j] += dp[j-nums[i]];dp含义:dp[j]表示为装满容量为j有dp[j]种方法。

2303_80070412的博客 1197

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

动态规划:13目标和

如何转化为01背包问题呢。 假设加法的总和为x,那么减法对应的总和就是sum - x。 所以我们要求的是 x - (sum - x) = target x = (target + sum) / 2 **此时问题就转化为,装满容量为x的背包,有几种方法**。 这里的x,就是bagSize,也就是我们后面要求的背包容量。 大家看到(target + sum) / 2 应该担心计算的过程中向下取整有没有影响。 这么担心就对了,例如sum 是5,target是2的话其实就是无解的,所以

曦煜墨白的博客 1060

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

目标和问题:从回溯到动态规划的旅程

定义dp[i][j]表示使用前i个数字,是否可以组成和为j的子集数。状态定义dp[i][j]表示使用前i个数字,是否可以组成和为j的子集数。状态转移方程:通过递推关系,逐步求解子问题,从而解决原问题。从后往前遍历:确保在计算新的dp[j]时,dp[j]和仍然是上一轮循环的结果,避免在当前轮次中使用已更新的值。从前往后遍历:可能会使用当前轮次已经更新的,导致错误的结果。希望这个解释能够帮助你更好地理解为什么在一维动态规划中需要从后往前遍历。如果还有任何问题,请随时告诉我!

like455的博客 1028

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

动态规划 目标和

摘要 本文介绍了解决「目标和」问题的动态规划方法。给定一个整数数组和目标值,通过在数字前添加正负号,计算使表达式结果等于目标的组合数。算法核心是将问题转化为子集和问题: 数学推导得出目标子集和公式:S = (target + sum)/2 使用动态规划求解:定义dp[j]为和为j的方案数,通过状态转移方程dp[j] += dp[j-num]计算 处理边界条件,包括目标值过大或(sum+target)为奇数的情况 算法时间复杂度O(n×S),空间复杂度O(S)。关键点在于问题转化、正确初始化dp[0]=1以及

红血哥 380

LeetCode 494. 目标和 动态规划详解

通过将问题转化为 01 背包问题,并结合动态规划技术,我们能够高效地解决目标和问题。动态规划的核心在于状态的定义和转移,是解决此类问题的有力工具。

Lentr0py的博客 984

【1.4】动态规划-解目标和

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

攻城狮7号的博客 843

494 目标和(动态规划)

1. 问题描述: 给你一个整数数组 nums 和一个整数 target 。向数组中的每个整数前添加'+' 或 '-' ,然后串联起所有整数,可以构造一个表达式 : 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。 返回可以通过上述方法构造的、运算结果等于 target 的不同表达式的数目。 示例 1: 输入:nums = [1,1,1,1,1], target = 3 输出:5 解释:一共有 5 种方法让最终目标和为.

二哈 300

动态规划 Leetcode 494 目标和

要点:1.想到±代表其实求的是连个组合的差值,进而记left为正组合,right为负组合,则有。2.想到以上面所求left为背包容量,得到dp[j]含义为装满背包容量j的组合方法数目;4.dp数组初始化时dp[0]为1,其余为0否则递推公式会无效。3.求组和数目的递推公式一般为。

weixin_46930685的博客 1215

【动态规划】494. 目标和

题目: 给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。 返回可以使最终数组和为目标数 S 的所有添加符号的方法数。 示例: 输入:nums: [1, 1, 1, 1, 1], S: 3 输出:5 解释: -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 一共有5种方法

weixin_43955488的博客 227

【力扣刷题笔记】动态规划-目标和

题目 494. 目标和 给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘+’ 或 ‘-’ ,然后串联起所有整数,可以构造一个 表达式 : 例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串联起来得到表达式 “+2-1” 。 返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/target

weixin_43887873的博客 378

动态规划巧解目标和

通过将问题转化为子集和问题,并利用动态规划技术,我们能够高效地计算出通过在每个数字前添加或来构造表达式,使得表达式的结果等于target的不同表达式的数目。这种方法显著减少了不必要的计算,提高了算法的执行速度。

2301_77749840的博客 373

动态规划:目标和

因为是求方式数,dp[0]初始化为1,不用非得死扣为什么为1,知道是为了推出正确答案才这么初始化就够了。本次和最后一块石头的重量2有异曲同工之妙,都是要分成两堆。正数的集合总和-负数的集合总和=目标和,那么怎么求出正数的集合;这道题开题解给我看的一脸懵,最后还是靠着手动画图才稍微明白。所以,正数的集合总和-(总和-正数的集合总和)=目标和。很难解释含义,只能靠带入递推公式,手动画表格理解。所以,正数的集合总和=(总和+目标和)/2。负数的集合总和=总和-正数的集合总和。正数的集合总和=最大背包重量。

m0_56176751的博客 332

动态规划-01背包问题-目标和

我们之前介绍了两道相对容易的01背包问题,这次我们来看下这道复杂点的背包问题,看题目:给你一个非负整数数组nums和一个整数target。向数组中的每个整数前添加'+'或'-',然后串联起所有整数,可以构造一个表达式例如,,可以在2之前添加'+',在1之前添加'-',然后串联起来得到表达式"+2-1"。返回可以通过上述方法构造的、运算结果等于target的不同表达式的数目。示例 1:5一共有 5 种方法让最终目标和为 3。示例 2:1。

m0_65369201的博客 1082
上一篇: 回文子串-中心拓展
下一篇: LRU 缓存
sunghosts
博客等级 码龄16年 58粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值