当前位置: 首页 > news >正文

算法系列--动态规划--⼦数组、⼦串系列(数组中连续的⼀段)(1)

💕"我们好像在池塘的水底,从一个月亮走向另一个月亮。"💕
作者:Mylvzi
文章主要内容:算法系列–动态规划–⼦数组、⼦串系列(数组中连续的⼀段)(1)
在这里插入图片描述

大家好,今天为大家带来的是算法系列--动态规划--⼦数组、⼦串系列(数组中连续的⼀段)(1),这是动态规划新的一种题型

1.最⼤⼦数组和

链接:
https://leetcode.cn/problems/maximum-subarray/
分析:

动态规划的子数组问题和前缀和问题是不一样的,

子数组和这道题要求的是子数组和的最大值,我们的状态表示就是记录以i位置为结束的所有子数组的最大和,而前缀和只是一种快速求出区间和的方法,并没有表示最大和这种状态

关于求最大子数组和问题这道题,要注意状态表示的含义以i位置为结尾的所有子数组的最大和,也就是必须以i位置为结尾,那么此时的状态其实只有两种:

  1. 单独一个
  2. 前面的一堆 + 它本身

网上的很多推到状态方程的时候其实很容易让人误解,解释的也不清楚,他们进行状态的分类是根据dp[i - 1]的正负来推导dp[i]的,有的人可能想为什么不判断nums[i]的正负呢?

其实本质都一样,笔者觉得单纯通过形式来推到方程更容易理解一些

子串/子数组问题的一个经验的状态分类就是按照长度分类的,因为他们的状态表示都比较固定,都是以i位置为结束的最大xxxx

有的题目还比较恶心(尤其是关于子串的问题),对于相同的子串有时候还需要去重,就需要额外开一个数组来统计次数

本题的分析思路:
在这里插入图片描述

代码:

class Solution {public int maxSubArray(int[] nums) {int n = nums.length;int dp = 0;int max = -0x3f3f3f3f;// 将最大/小值设置为+-ox3f3f3f3f是一种经验for(int num : nums) {dp = Math.max(num,dp + num);// 填表max = Math.max(max,dp);// 更新最值}return max;}
}

2.环形⼦数组的最⼤和

链接:
https://leetcode.cn/problems/maximum-sum-circular-subarray/description/
分析:

本题是上题的一个变种,这里带环了,对于带环的问题,我们最常用的一个做法是想办法将其转化为线性的,对于本题我们可以采用分类讨论的思想

根据什么区分类讨论呢?往往是根据最后结果可能出现的形式去考虑,对于本题,最长的子数组和可能是两种情况

  1. 不带环,在区间内部
  2. 带环,跨越区间

对于情况1,就是最大子数组和的解法,对于情况2,可以转化为求区间内的最小值,那么最大值就是sum - min,最后返回情况1和情况2的最大值即可

下面是详细分析过程

在这里插入图片描述

代码:

class Solution {public int maxSubarraySumCircular(int[] nums) {// 创建dp表int n = nums.length;if(n == 1) return nums[0];int[] f = new int[n];int[] g = new int[n];// 初始化f[0] = g[0] = nums[0];int max = -0x3f3f3f3f;int min = 0x3f3f3f3f;int sum = nums[0];// 填表for(int i = 1; i < n; i++) {f[i] = Math.max(nums[i],f[i - 1] + nums[i]);g[i] = Math.min(nums[i],g[i - 1] + nums[i]);max = Math.max(max,f[i]);min = Math.min(min,g[i]);sum += nums[i];}// 返回值return sum == min ? max : Math.max(max,sum - min);}
}

3.乘积最⼤⼦数组

链接:
https://leetcode.cn/problems/maximum-product-subarray/
分析:

首先想到的状态表示就是以i位置为结尾子数组的最大乘积,但是根据这个状态表示去推到状态转移方程时发现只使用一个dp表无法表示所有的情况

  • nums[i] > 0,i位置的状态就是前一个位置的最大乘积 * nums[i]
  • nums[i] < 0,此时无法通过dp[i - 1]来推到dp[i],因为一个负数 * 较大的数一定会变小,那么dp[i]存储的就是以i位置为结尾的子数组的最小乘积,这与我们的状态表示是矛盾的

既然当nums[i] < 0时,需要乘的是以i-1位置为结尾的子数组的最小乘积,那么我们就创建出一个dp表g[i]来表示最小乘积,以下是详细分析过程:
在这里插入图片描述

代码:

class Solution {public int maxProduct(int[] nums) {// 创建dp表int n = nums.length;int[] f = new int[n];int[] g = new int[n];// 初始化f[0] = g[0] = nums[0];int max = f[0];// 填表for(int i = 1; i < n; i++) {int t1 = 0, t2 = 0;if(nums[i] > 0) {f[i] = f[i - 1] * nums[i];g[i] = g[i - 1] * nums[i];}else {f[i] = g[i - 1] * nums[i];g[i] = f[i - 1] * nums[i];}f[i] = Math.max(nums[i],f[i]);g[i] = Math.min(nums[i],g[i]);max = Math.max(f[i],max);}return max;}
}

4.乘积为正数的最⻓⼦数组

链接:
https://leetcode.cn/problems/maximum-length-of-subarray-with-positive-product/description/
分析:

本题相较于上题有两个不同:

  1. 本题要求乘积必须为正数
  2. 本题求解的不是最大的乘积,而是乘积为正数的最长子数组

和上题一样,本题同样需要使用两个dp表来进行状态表示

  • f[i]:以i位置为结尾,乘积为正数的最大子数组长度
  • g[i]:以i位置为结尾,乘积为负数的最大子数组长度

状态转移方程推导如下:

在这里插入图片描述

注意特殊情况:

  • 当n[i] < 0时,f[i] == g[i - 1] + 1,但是如果i位置之前全是正数,此时g[i - 1] == 0,那么f[i] == 0 + 1 = 1了,但是因为n[i] < 0,i位置的f[i]应该等于 0,因为所有的以i位置为结尾的子数组的乘积必然为负数

代码:

class Solution {public int getMaxLen(int[] nums) {int n = nums.length;// 1.创建dp表int[] f = new int[n];int[] g = new int[n];// 2.根据状态表示进行初始化f[0] = nums[0] > 0 ? 1 : 0;g[0] = nums[0] < 0 ? 1 : 0;int max = -0x3f3f3f3f;// 3.填表for(int i = 1; i < n; i++) {if(nums[i] > 0) {f[i] = f[i - 1] + 1;g[i] = g[i - 1] == 0 ? 0 : g[i - 1] + 1;}else if(nums[i] < 0){f[i] = g[i - 1] == 0 ? 0 : g[i - 1] + 1;g[i] = f[i - 1] + 1;}else {f[i] = g[i] = 0;// 注意等于0相当于直接截断 要重新计数 从0开始}max = Math.max(f[i],max);// 更新长度}// 处理n == 1的情况return max == -0x3f3f3f3f ? f[0] : max;}
}

总结:

  • 子数组问题最常用的一种状态表示就是以i位置为结尾的xxxx
  • 在推导状态转移方程时,往往是根据组成子数组的形态来分类讨论(单独一个还是和前面一堆组成子数组)

相关文章:

算法系列--动态规划--⼦数组、⼦串系列(数组中连续的⼀段)(1)

&#x1f495;"我们好像在池塘的水底&#xff0c;从一个月亮走向另一个月亮。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;算法系列–动态规划–⼦数组、⼦串系列&#xff08;数组中连续的⼀段&#xff09;(1) 大家好,今天为大家带来的是算法系…...

RESTful架构

RESTful架构中的URI设计与传统的URL设计有一些区别。让我通过具体的例子来解释一下&#xff1a; 传统的URL设计通常将操作和资源混合在一起&#xff0c;例如&#xff1a; 获取所有图书&#xff1a;GET /getBooks获取特定图书&#xff1a;GET /getBookById/{id}创建新图书&…...

从IO操作与多线程的思考到Redis-6.0

IO操作->线程阻塞->释放CPU资源->多线程技术提升CPU利用率 在没有涉及磁盘操作和网络请求的程序中&#xff0c;通常不会出现线程等待状态。线程等待状态通常是由于线程需要等待某些事件的发生&#xff0c;比如I/O操作完成、网络请求返回等。如果程序只是进行计算或者简…...

MNN介绍、安装和编译

MNN是一个轻量级的深度学习推理框架&#xff0c;由阿里巴巴公司开发。它支持多种硬件平台&#xff0c;包括CPU、GPU和NPU&#xff0c;并提供高效、高性能的深度学习模型推理服务。下面是MNN的安装和编译步骤&#xff1a; 下载MNN源代码 在MNN的GitHub页面&#xff08;https://g…...

【计算机图形学】AO-Grasp: Articulated Object Grasp Generation

对AO-Grasp: Articulated Object Grasp Generation的简单理解 文章目录 1. 做的事情2. AO-Grasp数据集2.1 抓取参数化和label标准2.2 语义和几何感知的抓取采样 3. AO-Grasp抓取预测3.1 预测抓取点3.2 抓取方向预测 4. 总结 1. 做的事情 引入AO-Grasp&#xff0c;grasp propo…...

「媒体宣传」财经类媒体邀约资源有哪些?-51媒体

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 财经类媒体邀约资源包括但不限于以下几类&#xff1a; 商业杂志和报纸&#xff1a;可以邀请如《财经》、《新财富》、《经济观察报》等主流商业杂志和报纸。这些媒体通常具有较强的品牌影…...

学习资料记录

http://interview.wzcu.com/Golang/%E4%BB%A3%E7%A0%81%E8%80%83%E9%A2%98.html map底层 https://zhuanlan.zhihu.com/p/616979764 go修养 https://www.yuque.com/aceld/golang/ga6pb1#4b19dba5 https://golang.dbwu.tech/performance/map_pre_alloc/ https://juejin.cn/pos…...

数据结构进阶篇 之 【二叉树】详细概念讲解(带你认识何为二叉树及其性质)

有朋自远方来&#xff0c;必先苦其心志&#xff0c;劳其筋骨&#xff0c;饿其体肤&#xff0c;空乏其身&#xff0c;鞭数十&#xff0c;驱之别院 一、二叉树 1、二叉树的概念 1.1 二叉树中组分构成名词概念 1.2 二叉树的结构概念 1.3 特殊的二叉树 2、二叉树的存储结构 …...

vue.js制作学习计划表案例

通俗易懂&#xff0c;完成“学习计划表”用于对学习计划进行管理&#xff0c;包括对学习计划进行添加、删除、修改等操作。 一. 初始页面效果展示 二.添加学习计划页面效果展示 三.修改学习计划完成状态的页面效果展示 四.删除学习计划 当学习计划处于“已完成”状态时&…...

nginx localtion 匹配规则

1、语法规则 语法规则&#xff1a;location[|~|^~*|^~]/uri/{… } 表示精确匹配,这个优先级也是最高的 ^~ 表示 uri 以某个常规字符串开头&#xff0c;理解为匹配 url 路径即可。 nginx 不对 url 做编码&#xff0c;因此请求为 /image/20%/aa&#xff0c;可以被规则^~ /imag…...

Git:分布式版本控制系统

目录 Git的特点和功能常见的功能和对应的命令 Git的特点和功能 Git是一个分布式版本控制系统&#xff0c;用于跟踪和管理项目的代码变更。它是由Linus Torvalds在2005年创建的&#xff0c;旨在管理Linux内核的开发。Git具有以下特点和功能&#xff1a; 分布式版本控制&#xf…...

[STL]priority_queue类及反向迭代器的模拟实现

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 今日主菜&#xff1a; priority_queue类及反向迭代器 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;c大冒险 向着c&…...

vue2 脚手架

安装 文档&#xff1a;https://cli.vuejs.org/zh/ 第一步&#xff1a;全局安装&#xff08;仅第一次执行&#xff09; npm install -g vue/cli 或 yarn global add vue/cli 备注&#xff1a;如果出现下载缓慢&#xff1a;请配置npm 淘宝镜像&#xff1a; npm config set regis…...

【OpenStack】OpenStack实战之开篇

目录 那么,OpenStack是什么?云又是什么?关于容器应用程序OpenStack如何适配其中?如何设置它?如何学会使用它?推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战我的整个职业生涯到目前为止一直围绕着为离线或隔离网络设计和开发应用程…...

Python实现WebSocket通信

WebSocket是一种在单个TCP连接上进行全双工通信的协议,位于 OSI 模型的应用层。 与传统的HTTP请求-响应模型不同&#xff0c;WebSocket的最大特点就是&#xff0c;服务器可以主动向客户端推送信息&#xff0c;客户端也可以主动向服务器发送信息&#xff0c;实现实时性和互动性…...

MATLAB 自定义生成直线点云(详细介绍) (47)

MATLAB 自定义生成直线点云 (详细介绍)(47) 一、算法介绍二、具体步骤二、算法实现1.代码2.效果一、算法介绍 通过这里的直线生成方法,可以生成模拟直线的点云数据,并通过调整起点、终点、数量和噪声水平等参数来探索不同类型的直线数据。这种方法可以用于测试、验证和开…...

UniTask 异步任务

文章目录 前言一、UniTask是什么&#xff1f;二、使用步骤三、常用的UniTask API和示例1.编写异步方法2.处理异常3.延迟执行4.等待多个UniTask或者一个UniTas完成5.异步加载资源示例6.手动控制UniTask的完成状态7.UniTask.Lazy延迟任务的创建8.后台线程切换Unity主线程9.不要返…...

【git分支管理策略】如何高效的管理好代码版本

目录 1.分支管理策略 2.我用的分支管理策略 3.一些常见问题 1.分支管理策略 分支管理策略就是一些经过实践后总结出来的可靠的分支管理的办法&#xff0c;让分支之间能科学合理、高效的进行协作&#xff0c;帮助我们在整个开发流程中合理的管理好代码版本。 目前有两套Git…...

css的transition详解

CSS的transition属性是一个简写属性&#xff0c;用于设置四个过渡效果属性&#xff0c;以在元素的状态改变时创建平滑的动画效果。这四个属性分别是&#xff1a; transition-property&#xff1a; 定义应用过渡效果的CSS属性名称。当指定的CSS属性改变时&#xff0c;过渡效果将…...

agent利用知识来做规划:《KnowAgent: Knowledge-Augmented Planning for LLM-Based Agents》笔记

文章目录 简介KnowAgent思路准备知识Action Knowledge的定义Planning Path Generation with Action KnowledgePlanning Path Refinement via Knowledgeable Self-LearningKnowAgent的实验结果 总结参考资料 简介 《KnowAgent: Knowledge-Augmented Planning for LLM-Based Age…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...