LeetCode 494.目标和 (动态规划 + 性能优化)二维数组 压缩成 一维数组
494. 目标和 - 力扣(LeetCode)
给你一个非负整数数组 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
思路整理:可以将集合分为两个集合,一个加法集合(left),一个减法集合(right)
可以求出加法集合(left),将问题转换为求出left这个集合。详细讲解看下文~
left:表示加法集合
right:表示减法集合left + right = sum
left - right = target
left = (sum + target) / 2集合{1 1 1 1 1},分成left 和 right,生成的target如下:
left(加法集合) right(减法集合) target4 1 -33 2 12 3 -11 4 -3sum = 5
left = (sum + target) / 2
(O_O)?
发现并没有target = 2,于是当target = 2时,left = (2+5)/2 = 7/2 无法整除,
也就是 7 % 2 == 1 直接就 return 0 就好了表示找不出这样的集合能满足 left - right = target
此时问题转化为求出left这个集合,也就是说这个容器,
问在这个集合里边的所有元素装满这个容器有多少种方法?(妙啊~)有多少个元素能装满这个容器,我们就能找到符合这个题目条件的多少种
组合。此时发现这有点类似背包问题。那么left就是背包的容量,
集合{1 1 1 1 1}是物品集合
例子: nums = [1,2,1,3,1],target = -2,当这种情况的时候,left=3
(1)二维dp数组
dp[i][j] 表示在数组 nums 的前 i 个数中选取元素,使得这些元素之和等于 j 的方案数
比如说我们要计算元素之和 等于 3 的方案数,由于
0 + 3 = 3
1 + 2 = 3
2 + 1 = 3
所以我们可以把元素之和 等于 0,1,2的方案数分别计算出来,然后再相加就可以得到元素之和等于3的方案数。
当nums[0]=1时,
- nums[0]放不进去容量为0的背包
j=0,j<nums[0],那么dp[1][0] = dp[0][0] = 1
- nums[0]放得进去容量为1、2、3的背包
j=1,j>=nums[0],那么dp[1][1] = dp[0][1] + dp[0][1-nums[0]] = 0 + dp[0][0] = 0 + 1 = 1
j=2,j>=nums[0],那么dp[1][2] = dp[0][2] + dp[0][2-nums[0]] = 0 + dp[0][1] = 0 + 0 = 0
j=3,j>=nums[0],那么dp[1][3] = dp[0][3] + dp[0][3-nums[0]] = 0 + dp[0][2] = 0 + 0 = 0
以此类推~
思考🤔
当 j < nums[i-1]时
① dp[i][j] = dp[i-1][j]; //"copy"当j >= nums[i-1]时
② dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i-1]];将①和②整合起来
dp[i][j] = dp[i-1][j];
if(j>=nums[i-1]) {dp[i][j] += dp[i-1][j-nums[i-1]];
}
// 二维dp数组
class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0;int n = nums.size();int left = 0,right = 0;for(int i=0;i<n;i++) { sum += nums[i];}if (abs(target) > sum) return 0; // 此时没有方案if ((sum + target) % 2 == 1) return 0; // 此时没有方案left = (sum + target) / 2;vector<vector<int>> dp(n + 1, vector<int>(left + 1));dp[0][0] = 1;for (int i = 1; i <= n; i++) { // 物品for (int j = 0; j <= left; j++) { // 背包dp[i][j] = dp[i - 1][j];if (j >= nums[i-1]) {dp[i][j] += dp[i - 1][j - nums[i-1]];}}}return dp[n][left];}
};
思考🤔,压缩状态,将二维dp数组 优化为 一维dp数组


将二维dp数组压缩成一维dp数组!!! (重复利用实现滚动数组)
dp[j] += dp[j-nums[i]];dp[j] 装满容量为j的背包 有dp[j]种方法↑
dp[j-nums[i]] nums[i] dp[j-nums[i]] 1 dp[4] 凑成 dp[5]2 dp[3] 凑成 dp[5]3 dp[2] 凑成 dp[5]4 dp[1] 凑成 dp[5]5 dp[0] 凑成 dp[5]dp[5] = dp[4] + dp[3] + dp[2] + dp[1] + dp[0]也就是dp[j] += dp[j-nums[i]];初始化:dp[0] = 1
集合{0} target = 0 此时dp[0] = 1
// 一维dp数组
class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0;int left = 0,right = 0;for(int i=0;i<nums.size();i++) { sum += nums[i];}if (abs(target) > sum) return 0; // 此时没有方案if ((sum + target) % 2 == 1) return 0; // 此时没有方案left = (sum + target) / 2;vector<int> dp(left+1,0);dp[0] = 1;for(int i=0;i<nums.size();i++) { // 遍历物体for(int j=left;j>=nums[i];j--) { // 遍历背包dp[j] += dp[j - nums[i]]; }}return dp[left];}
};
相关文章:
LeetCode 494.目标和 (动态规划 + 性能优化)二维数组 压缩成 一维数组
494. 目标和 - 力扣(LeetCode) 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - ,然后串联起所有整数,可以构造一个 表达式 : 例如,nums [2, 1] ,可以在 2…...
[36c3 2019]includer
[36c3 2019]includer 题目描述:Just sitting here and waiting for PHP 8.0 (lolphp). 首先来了解一下临时文件包含之PHP - compress.zlib:// 在 php-src 里可以找到和 compress.zlib:// 有关的代码 | code 注意到 STREAM_WILL_CAST,涉及到 cast 经常…...
Python150题day10
④continue练习 从列表 Ist [1,3,5,2,7,9,10] 中输出所有的奇数,代码如下 lst [1, 3, 5, 2, 7, 9, 10] for item in lst: if item % 2 0: continue print(item) 在上述代码中,当遇到偶数时,continue 语句会跳过当前迭代&…...
Autosar工具-Davinci Developer
文章目录 前言一、Davinci Developer简介二、导航栏File(主要是用于保存、打开工程等操作)HomeProject(主要用于导入、导出arxml文件)Graphic(主要在SWC设计时使用,包含对图形界面下的设计工具)Window(主要就是对我们的Dev界面外形修改用的,使得界面更加方便我们使用(比如隐…...
js中的数据结构:栈,队列,链表,字典哈希表,树
栈:先进后出 队列:先进先出 链表: 单链表: 双链表: 环形链表:最后一个数据的next指针不是指向null,指向的是任意之间的一个数据,形成一个环 数组和链表的区别: 字典和哈…...
Verdi实现信号的平移
在Verilog/System verilog中,# xxx可以实现延迟指定时间的功能,而在使用verdi查看信号波形并进行分析时,同样也可以实现类似的功能。 (注:这种信号平移是有其应用场景的,例如,在某些仿真模型中,…...
Leetcode算法入门与数组丨6. 数组双指针、滑动窗口
文章目录 1 双指针基础知识1.1 双指针简介1.2 左右指针(对撞指针)1.3 快慢指针1.4 分离双指针 2 滑动窗口基础知识2.1 滑动窗口算法介绍2.2 滑动窗口适用范围2.3 固定长度滑动窗口2.4 不固定长度滑动窗口 1 双指针基础知识 1.1 双指针简介 双指针&…...
推荐一本书《横向领导力》
大家好,这里是大话硬件。 今天想给大家推荐一本我近期正在阅读的书籍《横向领导力》。 这本书很早就买了,但是在去年就看了前面3章的内容,而且也没做笔记,仅仅是在书本上写写画画,也没有什么体会,感觉看不懂…...
React实战过程的知识了解
做项目用到react和antd,没办法循序渐进的学习,只能把一些点记录在这里,希望大家指正。 1.杂七杂八 正文 //actionRef,操作表单的预设方法,包括:刷新、重置所有项并刷新、重置到默认项、加载更多、清空选…...
F对象和Q对象
F对象和Q对象 F对象 一个F对象代表数据库中某条记录的字段的信息 作用: 通常是对数据库中的字段值在不获取的情况下进行操作 用于类属性(字段)之间的比较 语法 from django.db.models import F F(列名)解决一种极端事件的产生,比如用户对一条微博的点赞…...
Visio——绘制倾斜线段
一、形状 -> 图表和数学图形 -> 多行 二、放置多行线,可以发现存在两个折点 三、选择多行线,右键选择删除点,即可得到倾斜线段...
Linux复习-安装与熟悉环境(一)
这里写目录标题 虚拟机ubuntu系统配置镜像Linux命令vi编辑器3个模式光标命令vi模式切换命令vi拷贝与粘贴命令vi保存和退出命令vi的查找命令vi替换命令 末行模式复制、粘贴、剪切gcc编译器 虚拟机 VMware16 官网下载:vmware官网 网盘下载: 链接ÿ…...
Go基础语法:map
9 map Go 语言中提供的映射关系容器为 map ,其内部使用 散列表(hash) 实现。它是一种无序的基于 key-value 的数据结构。 Go 语言中的 map 是引用类型,必须初始化之后才能使用。 9.1 map 定义 Go 语言中 map 的定义语法为&…...
开发板TFTP调试
问题描述 开发板和host(此处指虚拟机linux)可以平通,但是通过uboot tftp下载请求时一直显示T T T, 即超时 使用wireshark抓包也显示超时 措施 关闭windows和linux的防火墙 重新进行下载成功...
MySQL---优化日志
目录 一、MySQL优化 3、mysql server上的优化 3.1、MySQL查询缓存 3.2、索引和数据缓存 3.2、线程缓存 二、MySQL日志 2.1、redo log 重做日志 2.2、undo log 回滚日志 2.3、错误日志 2.4、查询日志 2.5、二进制日志 2.5.1、基于binlog数据恢复实践操作 六、慢查…...
【送面试题】深入解析Cookie和Session的请求区别及使用场景
AI绘画关于SD,MJ,GPT,SDXL百科全书 面试题分享点我直达 2023Python面试题 2023最新面试合集链接 2023大厂面试题PDF 面试题PDF版本 java、python面试题 项目实战:AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI…...
010_第一代软件开发(二)
第一代软件开发(二) 文章目录 第一代软件开发(二)项目介绍界面布局功能完善快照功能获取可用串口播放按键提示音 关键字: Qt、 Qml、 QSerialPort、 QPixmap、 QSoundEffect 项目介绍 欢迎来到我们的 QML & C 项目!这个项目结合了 QMLÿ…...
基于若依ruoyi-nbcio增加flowable流程待办消息的提醒,并提供右上角的红字数字提醒(四)
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 上一节说到待办系统的监听器TaskCreateListener,需要在flowable全局监听配置里加入配置 1、Glo…...
RestTemplate:简化HTTP请求的强大工具
文章目录 什么是RestTemplateRestTemplate的作用代码示例 RestTemplate与HttpClient 什么是RestTemplate RestTemplate是一个在Java应用程序中发送RESTful HTTP请求的强大工具。本文将介绍RestTemplate的定义、作用以及与HttpClient的对比,以帮助读者更好地理解和使…...
【数据结构】什么是数据结构?
数据结构(Data Structure)是计算机存储,组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合. 这么讲可能有些抽象,放一张图大家可能好理解一点: 上图依次是数据结构中逻辑结构中的:集合结构,线性结构,树形结构,图形结构. 而: 数据结构是一门研究非数值计算的程…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
对象回调初步研究
_OBJECT_TYPE结构分析 在介绍什么是对象回调前,首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例,用_OBJECT_TYPE这个结构来解析它,0x80处就是今天要介绍的回调链表,但是先不着急,先把目光…...
