零基础代码随想录【Day42】|| 1049. 最后一块石头的重量 II,494. 目标和,474.一和零

目录

DAY42

1049.最后一块石头的重量II

解题思路&代码

494.目标和

解题思路&代码

474.一和零

解题思路&代码


DAY42

1049.最后一块石头的重量II

力扣题目链接(opens new window)

题目难度:中等

有一堆石头,每块石头的重量都是正整数。

每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

如果 x == y,那么两块石头都会被完全粉碎;

如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。

最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。

示例:

  • 输入:[2,7,4,1,8,1]
  • 输出:1

解释:

  • 组合 2 和 4,得到 2,所以数组转化为 [2,7,1,8,1],
  • 组合 7 和 8,得到 1,所以数组转化为 [2,1,1,1],
  • 组合 2 和 1,得到 1,所以数组转化为 [1,1,1],
  • 组合 1 和 1,得到 0,所以数组转化为 [1],这就是最优值。

本题就和 昨天的 416. 分割等和子集 很像了,可以尝试先自己思考做一做。

视频讲解:动态规划之背包问题,这个背包最多能装多少?LeetCode:1049.最后一块石头的重量II_哔哩哔哩_bilibili

代码随想录

解题思路&代码

思路:

关键点:认识到什么是应用类背包问题,此处如何联系到背包?尽量把容器分成大小相等的两堆,则另一堆是否能用数组元素填满多少则是涉及到了背包最多能装多少的问题

本题其实就是尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了

是不是感觉和昨天讲解的416. 分割等和子集 (opens new window)非常像了。

本题物品的重量为stones[i],物品的价值也为stones[i]。

对应着01背包里的物品重量weight[i]和 物品价值value[i]。

1.确定dp数组以及下标的含义

dp[j]表示容量(这里说容量更形象,其实就是重量)为j的背包,最多可以背最大重量为dp[j]

可以回忆一下01背包中,dp[j]的含义,容量为j的背包,最多可以装的价值为 dp[j]。

2.确定递推公式

01背包的递推公式为:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

本题则是:dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);

3.dp数组如何初始化

既然 dp[j]中的j表示容量,那么最大容量(重量)是多少呢,就是所有石头的重量和。

因为提示中给出1 <= stones.length <= 30,1 <= stones[i] <= 1000,所以最大重量就是30 * 1000 。

而我们要求的target其实只是最大重量的一半,所以dp数组开到15000大小就可以了

4.确定遍历顺序

在动态规划:关于01背包问题,你该了解这些!(滚动数组) (opens new window)中就已经说明:如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历!

  • 时间复杂度:O(m × n) , m是石头总重量(准确的说是总重量的一半),n为石头块数
  • 空间复杂度:O(m)
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];//为什么要+1,因为涉及到背包重量为0的情况,要初始化,但是实际上数组元素是不包括这个的
        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];
    }
}

494.目标和

力扣题目链接(opens new window)

难度:中等

给定一个非负整数数组,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种方法让最终目标和为3。

大家重点理解 递推公式:dp[j] += dp[j - nums[i]],这个公式后面的提问 我们还会用到。

视频讲解:动态规划之背包问题,装满背包有多少种方法?| LeetCode:494.目标和_哔哩哔哩_bilibili

代码随想录

 

解题思路&代码

思路:

本题要如何使表达式结果为target,

既然为target,那么就一定有 left组合 - right组合 = target。

left + right = sum,而sum是固定的。right = sum - left

公式来了, left - (sum - left) = target 推导出 left = (target + sum)/2 。

target是固定的,sum是固定的,left就可以求出来。

此时问题就是在集合nums中找出和为left的组合

再回归到01背包问题,为什么是01背包呢?

因为每个物品(题目中的1)只用一次!

这次和之前遇到的背包问题不一样了,之前都是求容量为j的背包,最多能装多少。

本题则是装满有几种方法。其实这就是一个组合问题了。

1.确定dp数组以及下标的含义

dp[j] 表示:填满j(包括j)这么大容积的包,有dp[j]种方法

其实也可以使用二维dp数组来求解本题,dp[i][j]:使用 下标为[0, i]的nums[i]能够凑满j(包括j)这么大容量的包,有dp[i][j]种方法。

2.确定递推公式

有哪些来源可以推出dp[j]呢?

只要搞到nums[i],凑成dp[j]就有dp[j - nums[i]] 种方法。

例如:dp[j],j 为5,

  • 已经有一个1(nums[i]) 的话,有 dp[4]种方法 凑成 容量为5的背包。
  • 已经有一个2(nums[i]) 的话,有 dp[3]种方法 凑成 容量为5的背包。
  • 已经有一个3(nums[i]) 的话,有 dp[2]中方法 凑成 容量为5的背包
  • 已经有一个4(nums[i]) 的话,有 dp[1]中方法 凑成 容量为5的背包
  • 已经有一个5 (nums[i])的话,有 dp[0]中方法 凑成 容量为5的背包

那么凑整dp[5]有多少方法呢,也就是把 所有的 dp[j - nums[i]] 累加起来。

所以求组合类问题的公式,都是类似这种:

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

3.dp数组如何初始化

从递推公式可以看出,在初始化的时候dp[0] 一定要初始化为1,因为dp[0]是在公式中一切递推结果的起源,如果dp[0]是0的话,递推结果将都是0。

如果数组[0] ,target = 0,那么 bagSize = (target + sum) / 2 = 0。 dp[0]也应该是1, 也就是说给数组里的元素 0 前面无论放加法还是减法,都是 1 种方法。

所以本题我们应该初始化 dp[0] 为 1。

4.确定遍历顺序

在动态规划:关于01背包问题,你该了解这些!(滚动数组) (opens new window)中,我们讲过对于01背包问题一维dp的遍历,nums放在外循环,target在内循环,且内循环倒序。

5.举例推导dp数组

输入:nums: [1, 1, 1, 1, 1], S: 3

bagSize = (S + sum) / 2 = (3 + 5) / 2 = 4

dp数组状态变化如下:

  • 时间复杂度:O(n × m),n为正数个数,m为背包容量
  • 空间复杂度:O(m),m为背包容量
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 (Math.abs(target) > sum) return 0;
        //如果(target+sum)除以2的余数不为0,也是没有方案的
        if ((target + sum) % 2 == 1) return 0;

        int bagSize = (target + sum) / 2;
        int[] dp = new int[bagSize + 1];
        dp[0] = 1;

        for (int i = 0; i < nums.length; i++) {
            for (int j = bagSize; j >= nums[i]; j--) {
                dp[j] += dp[j - nums[i]];
            }
        }

        return dp[bagSize];
    }
}

474.一和零

力扣题目链接(opens new window)

给你一个二进制字符串数组 strs 和两个整数 m 和 n 。

请你找出并返回 strs 的最大子集的大小,该子集中 最多 有 m 个 0 和 n 个 1 。

如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。

示例 1:

  • 输入:strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3

  • 输出:4

  • 解释:最多有 5 个 0 和 3 个 1 的最大子集是 {"10","0001","1","0"} ,因此答案是 4 。 其他满足题意但较小的子集包括 {"0001","1"} 和 {"10","1","0"} 。{"111001"} 不满足题意,因为它含 4 个 1 ,大于 n 的值 3 。

通过这道题目,大家先粗略了解, 01背包,完全背包,多重背包的区别,不过不用细扣,因为后面 对于 完全背包,多重背包 还有单独讲解。

视频讲解:动态规划之背包问题,装满这个背包最多用多少个物品?| LeetCode:474.一和零_哔哩哔哩_bilibili

代码随想录

解题思路&代码

思路:

本题并不是多重背包,再来看一下这个图,捋清几种背包的关系

416.分割等和子集1

多重背包是每个物品,数量不同的情况。

本题中strs 数组里的元素就是物品,每个物品都是一个!

而m 和 n相当于是一个背包,两个维度的背包

理解成多重背包的同学主要是把m和n混淆为物品了,感觉这是不同数量的物品,所以以为是多重背包。

但本题其实是01背包问题!

只不过这个背包有两个维度,一个是m 一个是n,而不同长度的字符串就是不同大小的待装物品。

1.确定dp数组(dp table)以及下标的含义

dp[i][j]:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]

2.确定递推公式

dp[i][j] 可以由前一个strs里的字符串推导出来,strs里的字符串有zeroNum个0,oneNum个1。

dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1。

然后我们在遍历的过程中,取dp[i][j]的最大值。

所以递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);

此时大家可以回想一下01背包的递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

对比一下就会发现,字符串的zeroNum和oneNum相当于物品的重量(weight[i]),字符串本身的个数相当于物品的价值(value[i])。

这就是一个典型的01背包! 只不过物品的重量有了两个维度而已。

3.dp数组如何初始化

在动态规划:关于01背包问题,你该了解这些!(滚动数组) (opens new window)中已经讲解了,01背包的dp数组初始化为0就可以。

因为物品价值不会是负数,初始为0,保证递推的时候dp[i][j]不会被初始值覆盖。

4.确定遍历顺序

在动态规划:关于01背包问题,你该了解这些!(滚动数组) (opens new window)中,我们讲到了01背包为什么一定是外层for循环遍历物品,内层for循环遍历背包容量且从后向前遍历!

那么本题也是,物品就是strs里的字符串,背包容量就是题目描述中的m和n。

  • 时间复杂度: O(kmn),k 为strs的长度
  • 空间复杂度: O(mn) 
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];
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/638827.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Axure软件安装教程

链接&#xff1a;https://pan.baidu.com/s/1fHrSrZ7PIeDZZpn6QyJ6jQ?pwdb4mv 提取码&#xff1a;b4mv 安装完后点击Finish 名字随便起 关闭Axure 复制到安装目录下 最后成果

ASP+ACCESS基于WEB社区论坛设计与实现

摘要&#xff1a;系统主要实现BBS网站全部功能。采用目前应用最为广泛的ASP作为开发工具来开发此系统、以保证系统的稳定性。采用目前最为流行的网页制作工具Dreamweaver和目前最为流行的动画制作工具Flash MX。整个系统从符合操作简便、界面友好、灵活、实用、安全的要求出发&…

第七步 实现打印函数

文章目录 前言一、如何设计我们的打印函数&#xff1f;二、实践检验&#xff01; 查看系列文章点这里&#xff1a; 操作系统真象还原 前言 现在接力棒意见交到内核手中啦&#xff0c;只不过我们的内核现在可谓是一穷二白啥都没有&#xff0c;为了让我们设计的内核能被看见被使用…

uniapp微信小程序在ios端返回不显示弹窗的bug解决

这个问题其实是因为返回页面的时候弹的太快了导致的解决办法&#xff1a; 其实就是返回页面的弹窗加个延迟就好啦

电脑同时配置两个版本mysql数据库常见问题

1.配置时&#xff0c;要把bin中的mysql.exe和mysqld.exe 改个名字&#xff0c;不然两个版本会重复&#xff0c;当然&#xff0c;在初始化数据库的时候&#xff0c;如果时57版本的&#xff0c;就用mysql57(已经改名的)和mysqld57 代替 mysql 和 mysqld 例如 mysql -u root -p …

golang通过go-aci适配神通数据库

1. go-aci简介 go-aci是神通数据库基于ACI(兼容Oracle的OCI)开发的go语言开发接口&#xff0c;因此运行时需要依赖ACI驱动和ACI库的头文件。支持各种数据类型的读写、支持参数绑定、支持游标范围等操作。 2. Linux部署步骤 2.1. Go安装&#xff1a; 版本&#xff1a;1.9以上…

[数据集][目标检测]吸烟检测数据集VOC+YOLO格式1449张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1449 标注数量(xml文件个数)&#xff1a;1449 标注数量(txt文件个数)&#xff1a;1449 标注…

深度学习之基于Pytorch框架手写数字识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 手写数字识别是数字图像处理领域的一个经典问题&#xff0c;也是深度学习技术的一个常用应用场…

初识C语言——第二十八天

代码练习1&#xff1a; 用函数的方式实现9*9乘法表 void print_table(int n) {int i 0;int j 0;for (i 1; i< n; i){for (j 1; j< i; j){printf("%d*%d%-3d ", i, j, i * j);}printf("\n");}}int main() {int n 0;scanf("%d", &a…

【加密与解密(第四版)】第十六章笔记

第十六章 脱壳技术 16.1 基础知识 壳的加载过程&#xff1a;保存入口参数、获取壳本身需要使用的API地址、解密原程序各个区块的数据、IAT的初始化、重定位项的处理、HOOK API、跳转到程序原入口点 手动脱壳步骤&#xff1a;查找真正的入口点、抓取内存映像文件、重建PE文件&…

pod介绍之 容器分类与重启策略

目录 一 pod 基础概念介绍 1&#xff0c;pod 是什么 2&#xff0c;Pod使用方式 3&#xff0c;如何解决一个pod 多容器通信 4&#xff0c;pod 组成 5&#xff0c; k8s 中的 pod 二 pause容器 1&#xff0c;pause容器 是什么 2&#xff0c;pause容器作用 3&#xff…

Android studio关闭自动更新

Windows下&#xff1a; 左上角file - setting - Appearance & Behavier - system setting - update - 取消勾选

汉明码(海明码)的计算的规则

一.汉明码的由来 1.汉明码&#xff08;Hamming Code&#xff09;&#xff0c;是在电信领域的一种线性调试码&#xff0c;以发明者理查德卫斯里汉明的名字命名。汉明码在传输的消息流中插入验证码&#xff0c;当计算机存储或移动数据时&#xff0c;可能会产生数据位错误&#x…

vivado2020.2创建hls仿真工程实现led闪烁

下载vivado2020.2后会有这个出现在桌面 点击进入创建工程&#xff0c;这里注意不要有前面的\我再复制的时候复制错了导致创建失败 按f光标就会跳转到下一个f开头的函数处&#xff0c;要查找其他函数也同理 生成了一个synthesis summary文件 找到目录下生成的.v文件 an 点…

U-Mail邮件系统为用户提供更加安全的数据保护机制

据外媒报道&#xff0c;近日美国国家安全委员会泄露了其成员的近1万封电子邮件和密码&#xff0c;暴露了政府组织和大公司在内的2000家公司。其中包括美国国家航空航天局和特斯拉等。报道称该漏洞于3月7日被研究人员发现&#xff0c;通过该漏洞攻击者能够访问对web服务器操作至…

等保三级-MySQL 加固

1、身份鉴别 要求&#xff1a;建议身份密码登录&#xff0c;身份标识具有唯一性&#xff0c;身份鉴别信息具有复杂度要求&#xff0c;密码长度最少为8位&#xff0c;密码由数字、字母大小写、特殊符号组成、并设置定期更换&#xff0c;更换时间最长位90天 &#xff08;1&#…

asp.net core接入prometheus

安装prometheus和Grafana 参考之前的文章->安装prometheus和Grafana教程 源代码 dotnet源代码 新建.net core7 web项目 修改Program.cs using Prometheus;namespace PrometheusStu01;public class Program {public static void Main(string[] args){var builder We…

airflow2.7.3 + celery + redis + mysql 安装部署测试

集群环境&#xff1a; ​ 3台 centos 7.9 (dp95、dp96、dp97) python3.8 ​ dp96&#xff1a;mysql8.0.36(mysql8.0离线安装) ​ dp95\dp96\dp97&#xff1a;celery 集群(Celery安装测试) 安装目标&#xff1a; airflow2.7.3 mysql celery redis WebserverSchedulerwo…

Java 商品入库系统 案例

测试类 package 练习.商品入库系统;import java.util.ArrayList; import java.util.Scanner; public class Test {public static final int Enrool 1;public static final int Search 2;public static final int Delect 3;public static final int Exit 4;public static…

交换机部分综合实验

实验要求 1.内网IP地址使用172.16.0.0/16 2.sw1和sW2之间互为备份; 3.VRRP/mstp/vlan/eth-trunk均使用; 4.所有pc均通过DHcP获取Ip地址; 5.ISP只配置IP地址; 6.所有电脑可以正常访问IsP路由器环回 实验拓扑 实验思路 1.给交换机创建vlan&#xff0c;并将接口划入vlan 2.在SW1和…