代码随想录算法训练营Day42|1049.最后一块石头的重量II、494.目标和、474.一和零

最后一块石头的重量II

1049. 最后一块石头的重量 II - 力扣(LeetCode)

考虑昨天的能否将一个数组分为两个和相等的子集,本题有类似的思路,即将左右分为左右两个和相近的子集,然后返回其差值,这里使用动态规划的话。

DP数组含义,dp[j]表示能够达到的总重量为j的石头的最大重量

背包容量从0到1501(根据题目要求变化)

dp[j] = max(dp[j], dp[j-nums[i]] + nums[i]),j为重量,i为石头的选择与否。

遍历顺序同样物品遍历在外,背包遍历在内层,且内层倒序遍历。

最后考虑对最后一块石头重量的返回。考虑到dp[j]为其中一个子集所能抵达的最大重量,则另外一个子集的重量为总重量减去子集1的重量,要得到最后一块石头的重量,为两个子集和的相减值,最后的结果可以表示为sum -= 2*dp[j]。

class Solution {
public:int lastStoneWeightII(vector<int>& stones) {// 创建一个长度为1501,全0的数组dp,用于动态规划// dp[j]表示能够达到的总重量为j的石头的最大重量vector<int> dp(1501, 0);int sum = 0;// 计算stones数组中所有石头的总重量for (auto x : stones) {sum += x;}// 计算目标和,即分割后两堆石头的总重量应该接近sum/2const int target = sum / 2;for (int i = 0; i < stones.size(); i++) {// 从大到小遍历目标和及其以下的值for (int j = target; j >= stones[i]; j--) {// 更新dp[j],选取当前石头和不选取当前石头,取两种情况的最大值dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);}}// 最终结果为sum - dp[target]的两倍,因为dp[target]是接近sum/2的最大重量// 所以sum - dp[target]是另一堆石头的重量,两堆石头碰撞后剩下的最小重量就是它们的差return sum - 2 * dp[target];}
};

算法的时间复杂度为O(n^2),空间复杂度为O(n)。

目标和

494. 目标和 - 力扣(LeetCode)

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

得到目标和,需要在数字前面添加加号和减号,即存在两个数组我们假定为left数组和right数组,left数组中元素前全为加号,right数组中元素前全为减号。目标和为target,元素的所有和为sum。

sum_left + sum_right = target;

sum_left - sum_right = sum;

sum_left = (target + sum)/2,即我们能够得到left数组的和为target和元素和sum的一半。

使用动态规划算法来解决这个问题。

此时的dp[j]表示的是要装满容量为j的背包共有dp[j]种方式。

dp[j]:装满容量为j的背包有dp[j]种方式。

dp[j]的推导公式,这里需要牢记 dp[j]表示的是装满容量为j的背包的所有方式数量,所以dp[j]与dp[j-nums[j]]相关。即总容量为5,我们有一个质量为1的物品,则应该有dp[4]种方法能够得到5(1+4 = 5),若我们有一个质量为2的物品,应该有dp[3]种方法能够得到5(2+3 = 5 考虑之前的爬楼梯的题目),依次向下推,则dp[5] = dp[4] + dp[3] + dp[2] + dp[1] + dp[0]。

dp[j] += dp[j-nums[i]],此处为累加

dp[0]本应为0,但这里若初始为0,则所有dp均为0,所以初始化为1,非0下标初始化为0。

遍历顺序物品遍历在外,背包遍历在内层,且内层倒序遍历。

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0;// 计算数组nums中所有数字的和for (auto x : nums) {sum += x;}// 如果(target + sum)是奇数,那么不可能通过添加+或-得到target,因为每添加一个-,总和就会减少两倍if ((target + sum) % 2 == 1) {return 0;}// 如果target的绝对值大于sum,那么也不可能得到target,leetcode有反例[100] target -200if (abs(target) > sum) {return 0;}// 计算我们需要的正数总和leftconst int left = (sum + target) / 2;// 初始化动态规划数组dp,大小为left+1,初值都为0,dp[j]表示总和为j的方法数vector<int> dp(left + 1, 0);// 总和为0的方法只有1种,即不选择任何数字dp[0] = 1;// 遍历数组nums中的每个数字for (int i = 0; i < nums.size(); i++) {// 从大到小遍历left及其以下的值for (int j = left; j >= nums[i]; j--) {// 更新dp[j],考虑选择当前数字和不选择当前数字的情况dp[j] += dp[j - nums[i]];}}// 返回总和为left的方法数,即dp[left]return dp[left];}
};

算法的时间复杂度为O(n^2),空间复杂度为O(n)。

一和零

474. 一和零 - 力扣(LeetCode)

本题还是一个01背包问题,虽然有两个维度。具体参考如下网站

代码随想录 (programmercarl.com)

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

我们需要装满m个0,n个1的背包,共2个维度,需要一个二维的dp数组,背包中最多有多少个物品,dp[i][j]即表示最多背的物品个数,即最后返回值为dp[m][n]。

dp[i][j] = max(dp[i][j-1],dp[i][j]) x和y分别表示物品i中有x个0,y个1,此处max中的dp[i][j]参考之前背包问题的滚动数组,做了压缩。

对dp数组进行初始化,dp[0][0] = 0,其余值也全赋值为0。同样参考之前背包问题的滚动数组,dp[i][j]的值在每次遍历过程中会被覆盖。

遍历顺序,先遍历物品,再遍历背包,且背包要倒序遍历。

class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {// 初始化动态规划数组dp,大小为(m+1) x (n+1),初值都为0// dp[i][j]表示最多能组成多少个只包含0和1的字符串,且0的数量不超过i,1的数量不超过jvector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));// 遍历数组strs中的每个字符串for (string str : strs) {int zero_count = 0; // 记录当前字符串中0的数量int one_count = 0;  // 记录当前字符串中1的数量// 遍历当前字符串中的每个字符for (auto c : str) {if (c == '0') {zero_count++;} else {one_count++;}}// 从大到小遍历m和n,更新dp数组for (int i = m; i >= zero_count; i--) {for (int j = n; j >= one_count; j--) {// 更新dp[i][j],考虑选择当前字符串和不选择当前字符串的情况dp[i][j] = max(dp[i - zero_count][j - one_count] + 1, dp[i][j]);}}}// 返回最多能组成只包含0和1的字符串的数量,即dp[m][n]return dp[m][n];}
};

算法的时间复杂度为O(m*n*k),k为strs的长度,外层遍历str数组中的每个字符串,共有strs.size()次迭代,k为strs数组的总长度,为strs.size()*每个数组中元素的平均长度L。

空间复杂度考虑需要维护一个二维dp数组,为O(m*n)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【STM32】使用标准库点亮LED

1.硬件设计 LED1的阴极接到了PC13引脚上&#xff0c;我们控制PC13引脚的电平输出状态&#xff0c;即可控制LED1的亮灭。 2.编程要点 使能GPIO端口时钟&#xff1b;初始化GPIO目标引脚为推挽输出模式&#xff1b;编写简单测试程序&#xff0c;控制GPIO引脚输出高、低电平。 查…

Tomcat Websocket应用实例研究

概述 本文介绍了如何根据Tomcat给出的websocket实例&#xff0c;通过对实例的学习&#xff0c;定制自己基于websocket的应用。 环境及版本&#xff1a; Ubuntu 22.04.4 LTSApache Tomcat/10.1.20openjdk 11.0.23 2024-04-16浏览器&#xff1a;Chrome 相关资源及链接 Class…

python连接数据库,相关数据处理

随机生成一千个数据插入large_db中 # 这是一个示例 Python 脚本。# 按 ShiftF10 执行或将其替换为您的代码。 # 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。 import pandas as pd from sqlalchemy import create_engine from faker import Faker# 初始化fa…

AWS无服务器 应用程序开发—第十六章 CI/CD CodeBuild

在 AWS CodeBuild 中进行单元测试需要配置构建规范文件 (buildspec.yml),该文件定义了 CodeBuild 在构建过程中需要执行的步骤。以下是如何使用 CodeBuild 进行单元测试的具体步骤: 准备项目结构 首先,确保你的项目具有适当的目录结构和测试文件。以下是一个示例项目结构:…

加密excel(Python)

文章目录 一、EXCEL加密 一、EXCEL加密 import randomfrom win32com.client import Dispatchdef random_password(length20):默认返回20位随机密码key ""characters "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"for i in range(l…

Airflow 中的trigger_rule

最近正在使用airflow&#xff0c;用到了这个&#xff0c;记录下 在 Apache Airflow 中&#xff0c;trigger_rule 是用于控制任务何时被触发的规则。TriggerRule 是一个枚举类型&#xff0c;它包含了多种不同的触发规则。以下是这些规则及其用途的详细说明&#xff1a; ALL_SUC…

【价值主张画布】以产品思维,将自己打造成“爆款”

经营自己等于经营公司&#xff1a; 1.客户细分&#xff1a;我能帮助谁&#xff1f;谁是我们最重要的客户&#xff1f; 2. 客户关系&#xff1a;怎样和对方打交道&#xff1f;一次交付还是持续交付&#xff1f; 3.渠道通路&#xff1a;怎样宣传自己和服务&#xff1f; 4. 价值主…

Jmeter 性能测试步骤是什么?

性能测试是软件开发过程中非常重要的一环。它可以帮助我们评估软件系统在不同负载下的性能表现&#xff0c;找出系统中的性能瓶颈&#xff0c;并提供改进方案。而JMeter作为一款功能强大且广泛使用的性能测试工具&#xff0c;可以帮助我们实现这一目标。 下面&#xff0c;我将…

银河麒麟4.0.2安装带有opengl的Qt5.12.9

银河麒麟4.0.2下载地址&#xff1a;银河麒麟-银河麒麟(云桌面系统)-银河麒麟最新版下载v4.0.2-92下载站 VirtualBox:https://www.virtualbox.org/wiki/Downloads qt下载&#xff1a;Index of /archive/qt/5.12/5.12.9 1安装VirtualBox:网上教材比较多 1&#xff09;安装完后安…

方法论:SWOT、SMART

解决方案分析方法论SWOT 什么是SWOT&#xff1a;例子中间件RabbitMQ和RocketMQ队列选择对比S&#xff08;strengths&#xff09;优势&#xff1a;RabbitMQ团队多人用过&#xff0c;AMQP跨语言、模型API丰富W&#xff08;weaknesses&#xff09;劣势&#xff1a;RabbitMQ阅读过…

GooglePlay | 发布APK步骤

将生成好的 APK 包上传到 Google Play 商店涉及几个步骤。以下是详细指南&#xff1a; 1. 创建 Google Play 开发者账户 如果你还没有 Google Play 开发者账户&#xff0c;需要先创建一个&#xff1a; 访问 Google Play Developer Console.注册并支付一次性注册费&#xff0…

SAP ABAP开发过程中内表的概念及操作详解之三

八. 汇总表字段 汇总表字段&#xff08;Summarizing Table Fields&#xff09;是在ABAP编程中对内部表的数据进行汇总和计算的过程。这通常涉及到对数值字段进行求和、计数、平均值等计算。以下是汇总表字段的详细说明&#xff1a; 1. 使用COLLECT语句&#xff1a; COLLECT语…

干货 | 使用 Navicat BI 解锁数据的力量

商业智能&#xff08;BI&#xff09;是一种将数据转化为可执行洞察的实践&#xff0c;能够帮助业务领导者提升整体业绩。这个过程中最重要的一个阶段是数据探索和可视化阶段&#xff0c;它涉及通过报告将数据组织并转化为有意义的信息。为了让数据更易于理解&#xff0c;BI 专业…

第十一站:Java翡翠绿——大数据处理的力量

在Java大数据处理领域&#xff0c;Hadoop和Spark是两个至关重要的框架&#xff0c;它们充分展示了Java在处理大规模数据集方面的实力。下面我将通过简化的范例来讲解这两个框架的基本使用。 Hadoop MapReduce 示例 Hadoop MapReduce 是一种编程模型&#xff0c;用于处理和生成…

opencv 打开图片后,cv::mat存入共享内存的代码,以及如何设置共享内存的大小?图片的3840x2160 pixels

opencv 打开图片后&#xff0c;cv::mat存入共享内存的代码&#xff0c;以及如何设置共享内存的大小&#xff1f;图片的3840x2160 pixels。 在OpenCV中&#xff0c;将cv::Mat对象存入共享内存需要几个步骤。首先&#xff0c;你需要创建一个共享内存区域&#xff0c;然后将cv::Ma…

DashText-进阶使用

前置知识 BM25简介 BM25算法&#xff08;Best Matching 25&#xff09;是一种广泛用于信息检索领域的排名函数&#xff0c;用于在给定查询&#xff08;Query&#xff09;时对一组文档&#xff08;Document&#xff09;进行评分和排序。BM25在计算Query和Document之间的相似度…

好文!12个策略解决 Kafka 数据丢失问题

哥们儿&#xff01;有遇到Kafka数据丢失问题的问题吗&#xff0c;你是如何解决的&#xff1f;今天的文章&#xff0c;V哥来详细解释一下&#xff0c;整理了12种解决策略&#xff0c;希望可以帮助你解决项目中的问题&#xff1a;以下是一些常见的解决方案和最佳实践。 生产者确认…

四川赤橙宏海商务信息咨询有限公司正规吗?

在数字化浪潮席卷全球的今天&#xff0c;电商行业正以前所未有的速度蓬勃发展。作为这一潮流的佼佼者&#xff0c;抖音电商以其独特的短视频直播模式&#xff0c;吸引了大量消费者和商家的目光。在这一背景下&#xff0c;四川赤橙宏海商务信息咨询有限公司应运而生&#xff0c;…

2Y0A21 GP2Y0A21YK0F 红外测距传感器 arduino使用教程

三根线 正极负极信号线 确认自己的三根线分别代表什么&#xff0c;我们的颜色可能不一样 附一张我买的传感器他们的说明图 正极 接 开发板5V 负极 接开发板GND 信号线 接A0 代码arduino ide上面写 // Infračerven senzor vzdlenosti Sharp 2Y0A21// připojen potře…

2024最新AI大模型-LLm八股合集(三)

常见的大模型 1.ChatGLM 1.1 背景 主流的预训练框架主要有三种&#xff1a; autoregressive自回归模型&#xff08;AR模型&#xff09; &#xff1a;代表作GPT。本质上是一个left-to-right的语言模型。 通常用于生成式任务 &#xff0c;在长文本生成方面取得了巨大的成功…