代码随想录算法训练营第四十二天 | LeetCode 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零
代码随想录算法训练营第四十二天 | LeetCode 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零
文章链接:最后一块石头的重量 II 目标和 一和零
视频链接:最后一块石头的重量 II 目标和 一和零
1. LeetCode 1049. 最后一块石头的重量 II
1.1 思路
- 这题不要被题目的示例给带偏,其实就是看看我们能不能把石头尽量分成两堆,比如示例的总和为 23,看看能不能分成一半就是 11,另一半就是 12 了,一相撞就是剩下 1 了。即尽量分成重量总和近似相等的两堆,就是想到本题的关键了,这么看和416. 分割等和子集还是很像的,区别就是那题是能分成子集相等的就是 true 反之 false,本题是尽量凑,凑不成就相撞所剩下的重量也是最小的。
- dp 数组的下标及其含义:在 01 背包中,背包容量为 j 所能带的最大价值为 dp[j]。但本题的重量/容量也是它的价值,所以这里的最大价值也是它的最大重量,背包容量为 j 所能带的最大重量为 dp[j]
- 递推公式:在 01 背包中,dp[j]=Math.max(dp[j],dp[j-weight[i]]+value[i]),前者是不放物品 i,后者是放物品 i。在本题中 dp[j]=Math.max(dp[j],dp[j-stones[i]]+stones[i]),前者是不放石头 i,后者是放石头 i
- dp 数组的初始化:dp[0]=0,容量 0 的背包能放的重量也是 0。其他下标初始化为 0,因为我们的递推公式是通过别的值覆盖 dp[j] 的,因此不能初始化太大,为 0 最正确。我们这里定义 dp 数组的大小就是,先求 sum,target=sum/2,dp 数组的大小就是 target+1,因为我们要凑容量的一半
- 遍历顺序:两层 for循环,for(int i=0;i<stones.length;i++)for(int j=target;j>=stones[i];j–)先物品后背包,然后背包这一层从后往前遍历,这里为什么j>=stones[i] 是因为如果背包容量比石头重量还小再遍历就没有意义了
- 打印 dp 数组:用于 debug
- 最后 return sum-2*dp[target]
1.2 代码
class Solution {public int lastStoneWeightII(int[] stones) {int sum = 0;for (int i : stones) {sum += i;}int target = sum >> 1;//初始化dp数组int[] dp = new int[target + 1];for (int i = 0; i < stones.length; i++) {//采用倒序for (int j = target; j >= stones[i]; j--) {//两种情况,要么放,要么不放dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);}}return sum - 2 * dp[target];}
}
2. LeetCode 494. 目标和
2.1 思路
- 我们可以在集合中加入“+”“-”变为一个表达式,使其等于我们的 target。关于放“+”还是“-”就是把这个集合分成了两个集合,放加法的是一个集合,放减法的是一个集合。本题和416. 分割等和子集也是一个集合里分两个子集还有1049. 最后一块石头的重量 II也是一个集合里分出两个子集。本题中我们加法用 left,减法用 right,加法和减法的集合就是原集合的总和 sum,要求加法集合 left-减法集合 right=target,一相加就是 2left=sum+target => 即 left=(sum+target)/2。举例 [1,1,1,1,1] 即 sum=5,题目的 target=3,因此 left=(5+3)/2,就是 4 个用加法,1 个用减法,我们求出 left 集合剩下的就是 right 集合了。当然也是有用例是求不出 left 集合的,比如如果上面的是 target=2,那我们的 left 和 right 都找不到一种匹配的集合等于 target,因此如果判断出 (target+sum)%2!=0 就最终输出 0。此时问题转化为,求出 left 集合,原集合里所有元素装满这个 left 集合有多少种方法,就能找到符合题目条件的多少种组合,这就是背包问题了,left 就是背包容量,原集合就是我们的物品
- 纯 01 背包就是问装满这个背包的最大价值,416. 分割等和子集就是能不能装满这个背包,满了就 true 否则就 false,1049. 最后一块石头的重量 II结束尽量去装,能装多少装多少,本题就是给我们一个容量,问有多少种方式能把背包装满
- dp 数组及其下标的含义:dp[j] 装满背包容量为 j 有 dp[j] 种方法。bagSize=(target+sum)/2
- 递推公式:dp[j]+=dp[j-nums[i]]
- dp 数组的初始化:在 01 背包中 dp[0] 初始化为 0,即背包容量为 0 的背包最大价值是 0,但是本题,dp[0] 应该初始化为 1,因为我们的 dp[j] 是通过前面累加的,如果初始化为 0,后面就一直是 0 了
- 遍历顺序:01 背包中先物品再背包,因此 for(int i=0;i<nums.length;i++)for(int j=bagSize;j>=nums[i];j–)第二层倒序遍历,然后 dp[j]+=dp[j-nums[i]]
- 打印 dp 数组:用于 debug
2.2 代码
class Solution {public int findTargetSumWays(int[] nums, int target) {int sum = 0;for (int i = 0; i < nums.length; i++) sum += nums[i];//如果target过大 sum将无法满足if ( target < 0 && sum < -target) return 0;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];}
}
3. LeetCode 474. 一和零
3.1 思路
- 本题让我们从题目的集合中找出一个最多元素的子集,满足有 m 个 0,n 个 1。可以把 m 个 0 和 n 个 1 理解为一个背包,有两个维度,最多有 m 个 0 和 n 个 1,而集合里的元素就是物品。但这题不是多重背包,还是 01 背包,每个物品只能是使用 1 次,只是有两个维度。而多重背包是会限制物品的个数。
- 纯 01 背包就是问装满这个背包的最大价值,416. 分割等和子集就是能不能装满这个背包,满了就 true 否则就 false,1049. 最后一块石头的重量 II结束尽量去装,能装多少装多少,494. 目标和就是给我们一个容量,问有多少种方式能把背包装满,本题是求装满这个背包最多有多少个物品
- dp 数组及其下标的含义:我们是要装满一个 m 个 0、n 个 1 这么大容器的背包,这个背包里最多有多少个物品,一共 3 个变量,m、n、多少个物品。两个维度 m 个 0、n 个 1,因此定义个二维 dp 数组,含义是最多有 i 个 0 j 个 1 的 strs 的最多有 dp[i][j] 个物品,最终 dp[m][n] 就是我们的结果
- 递推公式:纯 01 背包的公式是 dp[j]=Math.max(dp[j],dp[j-weight[i]]+value[i]),本题中我们物品的重量就是 x 个 0 y 个 1,整个背包最大重量是 m 个 0 n 个 1。因此 dp[i-x][j-y]+1,这里减去的 x 和 y 就是物品的重量,+1 就是物品的价值,价值就是个数,我们求的就是最多个数。可以这么理解:放了物品 i,还剩下 j - weight[i] 的容量可以放其他物品,剩下空间能得到的最大价值是 dp[i-1][j-weight[i]] 这句话是引用 01 背包理论基础的,理解一下。因此 dp[i][j]=Math.max(dp[i][j], dp[i-x][j-y]+1)
- dp 数组的初始化:dp[0][0]=0,背包容量为 0 了,最大的物品个数自然也是 0。非 0 下标 dp[i][j] 物品个数不会是负数,因此初始化为 0,就不会在递推时 dp[i][j] 被初始化值覆盖掉
- 遍历顺序:也是"两层"for循环,先物品再背包。先通过增强 for循环遍历 str,每遍历到一个物品就要用 x 和 y 记录有几个 0 和 1。然后就是遍历背包,这里是要遍历 0 和 1,我们是先 0 再 1,不过可以颠倒,但是要倒序遍历, for(int i=m;i>=x;i–)for(int j=n;j>=y;j–)
- 打印 dp 数组:用于 debug
3.2 代码
class Solution {public int findMaxForm(String[] strs, int m, int n) {//dp[i][j]表示i个0和j个1时的最大子集int[][] dp = new int[m + 1][n + 1];int oneNum, zeroNum;for (String str : strs) {oneNum = 0;zeroNum = 0;for (char ch : str.toCharArray()) {if (ch == '0') {zeroNum++;} else {oneNum++;}}//倒序遍历for (int i = m; i >= zeroNum; i--) {for (int j = n; j >= oneNum; j--) {dp[i][j] = Math.max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);}}}return dp[m][n];}
}
相关文章:

代码随想录算法训练营第四十二天 | LeetCode 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零
代码随想录算法训练营第四十二天 | LeetCode 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零 文章链接:最后一块石头的重量 II 目标和 一和零 视频链接:最后一块石头的重量 II 目标和 一和零 1. LeetCode 1049. 最后一块石头的重量 II 1.1 思路…...
Windows PowerShell 和 Linux BashShell 极简对比
声明:本文不会涉及原理,详细的介绍,也不是入门文章。仅仅从使用上进行简单比较 命令 在 bash 中,一个命令是一个单独的进程;而在 PowerShell 中,命令被称为 cmdlets,他们不是独立的可执行程序&…...

校验验证码是否过期(定时刷新验证码)
需求: 我们在登录的时候会遇到通过接口请求验证码的操作,这里的验证码会有过期的时间,当我们验证码过期了,我们要进行重新刷新验证码。 我们这里根据后端返回的当前时间和过期时间判断,过期的时间超过了当前时间的时候…...
windows idea本地执行spark sql避坑
本地安装了IDEA,并配置好了相关POM,可以在本机使用sparkSession连接数据,并在数据库执行sql,在idea展示执行结果。 但是,如果将数据的查询结果建立到spark中,再展示,就会报错 Error while run…...

在一个循环链队中只有尾指针(记为rear,结点结构为数据域data,指针域next),请给出这种队列的入队和出队操作实现过程
在一个循环链队中只有尾指针(记为rear,结点结构为数据域data,指针域next),请给出这种队列的入队和出队操作实现过程 入队过程如下图: 先创一个结点,用于存储要插入的结点数据 然后就是老套路了…...

智能客服系统应用什么技术?
随着科技的飞速发展,智能客服系统逐渐出现在我们的生活中。这些系统不仅能够提供即时的客户服务,还可以通过人工智能等技术实现更加高效和准确的服务。那么,智能客服系统究竟应用了哪些技术呢?本文将详细解析。 1、机器学习技术 …...

亚马逊、美客多卖家测评:如何建立养号团队实现运营化式测评?
大家好,我是跨境电商测评养号7年从事经验的珑哥。养号环境软件开发,深度解决各跨境平台矩阵养号防关联、砍单、F号问题。关注珑哥解决更多跨境养号测评问题。 测评,相信这个词对于大部分跨境卖家来说,想必都不陌生,因…...

苹果IOS系统webglcontextlost问题-解决方案
问题描述 在IOS手机 解码视频流的时候,第一次可以正常播放,但只要IOS手机熄屏,再重新唤醒,就会一直播放失败,无论换哪个浏览器都不行。安卓手机则一切正常。 经过排查,发现 IOS手机 的浏览器会无故 webGL…...
供应链ERP之合同:创建、修订与模板
本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…...

MySQL第二讲·表的创建与修改
你好,我是安然无虞。 文章目录 表:怎么创建和修改数据表?1. 如何创建数据表?2. 都有哪些约束?3. 如何修改表?添加字段修改字段 表:怎么创建和修改数据表? 创建和修改数据表&#x…...
springboot的循环依赖问题描述及解决方案
一.了解循环依赖的场景 在Spring Boot中,循环依赖是指两个或多个Bean之间相互依赖,导致它们无法正确地创建和注入。循环依赖可能会导致应用程序无法启动或出现其他异常。 在以下情况下,您可能需要显式设置循环依赖: 两个Bean相…...

当科技遇上神器:用Streamlit定制AI可视化问答界面
Streamlit是一个开源的Python库,利用Streamlit可以快速构建机器学习应用的用户界面。 本文主要探讨如何使用Streamlit构建大模型外部知识检索的AI问答可视化界面。 我们先构建了外部知识检索接口,然后让大模型根据检索返回的结果作为上下文来回答问题。…...
毛泽东思想和中国特色社会主义理论概论平时作业四
毛泽东思想和中国特色社会主义理论概论平时作业四 1.单选题 1.1人民代表大会制度是中国人民当家作主的基本政治制度,是我国的国体。(b) a.正确 b.错误 人民代表大会制度是中国人民当家作主的根本政治制度,是我国的政体。1.2我国的政体是人民民主专政。…...

微信怎么设置自动通过好友申请?
当开展引流获客活动时,员工会在一段时间内频繁收到好友添加的申请,手动同意好友请求费时费力还容易出现漏加的情况,那么微信能自动通过好友请求吗? 如何设置快速自动通过好友申请呢? 当微信号在系统登录,…...
亲测解决Pytorch TypeError: object of type ‘numpy.int64‘ has no len()
这个问题是小虎在初始化自适应平均池化的时候遇到的,解决方法是限制初始化时池化大小的类型。 问题原文 Exception has occurred: TypeError object of type numpy.int64 has no len()File "D:\Complier\LEF\lib\model\segmentation\heads\modules\fgModules…...
前端模拟实现可编辑的表格table插件
在做项目中遇到了一个供货记录的功能,要求用户自己编辑添加删除表格数据,接下来我们就模拟下前端如何实现该功能 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta http-equiv"X-…...

PerfectPixel 插件,前端页面显示优化工具
1.简介 PerfectPixel 插件是一款适用于 Chrome 浏览器的网页前端页面显示优化工具,该插件能够帮助开发人员和标记设计人员在开发时将设计图直接加载至网页中,与已成型的网页进行重叠对比,以规范网页像素精度 作为一款可以优化前端页面显示的…...

mysql迁移data目录(Linux-Centos)
随着时间的推移,mysql的数据量越越大,使用yum默认安装的目录为系统盘 /var/lib/mysql,现重新挂载了一个硬盘,需要做数据目录的迁移到 /mnt/data/。以解决占用系统盘过高情况。 1.强烈建议这种操作。镜像一个一样的Centos系统&…...
linux-等保测评
#查看审计规则 #auditctl -l #添加审计规则 #auditctl -w /etc/passwd -p rwxa(注意:用 auditd 添加审计规则是临时的,立即生效,但是系统重启失效。) #-w path : 指定要监控的路径,上面的命令指定了监控的文…...
一、React基础知识
一、环境安装 第一种:使用原生搭建(可以从国内下载配置镜像、也可以从国外下载) 指令:1.国内下载:(1:npm config set registry https://r.npm.taobao.org// (2:npm install -g create-react-app…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...