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

高频算法:Leetcode53 最大子数组和

今天讲的是Leetcode第53题,最大子数组和
最大子数组和
首先观察题目,题目需要我们找出具有最大和的连续子数组,直接拿题目中的示例来做一个演示,找一找什么规律下的连续子数组才能得到最大的和

先从-2开始,-2 + 1 = -1 此时我们的和是一个负数,那么无论后面的数是什么,这个数加上-1一定是更小了,所以-2这个值我们不应该加入到我们的结果子数组中
接下来是1 - 3 = -2,还是一个负数,跟上面一样,我们不需要负数,接下来的-3我们也不要了
此时从4开始找连续的子数组,4 - 1 = 3,是个正数,还能接受,就接着往后加
3 + 2 + 1 = 6,到这里为止,我们得到了迄今为止最大的子数组和
6 - 5 = 1,还是一个正数,还可以接着往后加,1 + 4 = 5,到这里为止整个数组都遍历完了
我们发现最大的子数组和是6,连续子数组为[4, -1, 2, 1]

通过我们对于示例的拆解,我们可以发现一个规律,那就是如果我们在遍历数组的时候,一旦加和为负数的话,这个和就对我们最终的解存在负面效果,所以当前遍历的数组元素就不会在我们的最大连续子数组中
同时我们在得到更大的和时,需要记录下来这个最大的值,因为后面的加和过程中,虽然整体是正数,但也不一定就是最大的,通过这两个条件我们就可以得到我们想要的最大和了

此时我们就可以得到本道题的第一个解法

public int maxSubArray(int[] nums) {int result = Integer.MIN_VALUE, sum = 0;for (int i = 0; i < nums.length; i++) {// 遍历数组并进行元素的累加sum += nums[i];// 如果返回的解小于当前我们当前子数组累加的和的话,就重新对解赋值,保证这个解一直是最大的if (result < sum) {result = sum;}// 如果子数组的和是负数的话,就舍弃掉当前已经遍历过的子数组,清零后接着往后遍历if (sum < 0) {sum = 0;}}return result;
}

通过上面发现的规律,我们还可以使用动态规划来解决这道题,首先需要明确的是状态转移方程是怎样的,先将当前的问题进行一下拆解,如果我们要得到最大子数组和,我们需要知道哪些子问题(依旧使用示例来描述)

  1. 如果我们的最大子数组包含-2,最大子数组是什么样的
  2. 如果我们的最大子数组包含1,最大子数组是什么样的
  3. 如果我们的最大子数组包含-3,最大子数组是什么样的
    依次类推,直到数组中的最后一个元素…
  4. 如果我们的最大子数组包含4,最大子数组是什么样的

但是这样定义的话,又不能明确当前这个元素是在数组的哪个位置,不满足动态规划的「无后效性」,简单来说就是有不确定性,这个时候,就需要将子问题定义的更加严格,直接指定子问题中的元素是子数组的最后一个元素,那么我们的子问题就变成了:

  1. 如果我们的最大子数组的最后一个元素是-2,最大子数组是什么样的
  2. 如果我们的最大子数组的最后一个元素是1,最大子数组是什么样的
  3. 如果我们的最大子数组的最后一个元素是-3,最大子数组是什么样的
  4. 如果我们的最大子数组的最后一个元素是4,最大子数组是什么样的

子问题定义完了,那么我们的状态转移方程应该是什么样的呢?我们从第一个子问题出发梳理一下:
如果最后一个元素是-2,那么这个最大子数组其实就是[-2],因为也只有一个元素
如果最后一个元素是1,最大子数组和是 -2 + 1 = -1,这个情况下我们的状态转移方程是dp[i] = dp[i - 1] + nums[i];如果我们将1这个元素换成一个负数,比如说 -1,那么这个子数组和是 -2 - 1 = -3,所以最大子数组和就是 -1,-2就被舍弃掉了
最终我们得到的状态转移方程是dp[i] = Math.max(dp[i - 1] + nums[i], nums[i ])

通过上面的分析,我们可以写出使用动态规划来解决问题的代码

public int maxSubArray(int[] nums) {// 将第一个元素先赋值,这样即使数组只有一个元素也不会出问题int result = nums[0];int[] dp = new int[nums.length];// dp[0]的解是确定的dp[0] = nums[0];for (int i = 1; i < nums.length; i++) {// 状态转移方程dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);// 将子问题中最大的和存起来作为结果返回result = Math.max(result, dp[i]);}return result;
}

本人能力有限,可能理解表达不太到位,建议还是看Leetcode上大佬的题解来理解动态规划的思路官网题解

最后一种是题目中提到的分治法,分治法的核心思路也是将一个父问题拆成多个子问题来解决,还是拿题目的示例画一张图来理解一下
分治法思路
[-2,1,-3,4,-1,2,1,-5,4]作为一个完整的数组被分为3部分分别计算最大子数组和:

  1. L部分计算[left, mid]
  2. R部分计算[mid + 1, right]
  3. M部分计算包含mid和mid + 1这两个元素的部分,左边最长延伸到left,右边最长延伸到right

同时对于L和R这两个部分,又可以递归的往下计算分别的最大子数组和,比如L部分,[-2,1,-3,4,-1]这个数组可以继续往下进行分治,直到计算出结果为止

public int maxSubArray(int[] nums) {return maxSubArrayDivide(nums, 0, nums.length - 1);
}private int maxSubArrayDivide(int[] nums, int left, int right) {if (left == right) {return nums[left];}int mid = (right - left) / 2 + left;// 三个部分取最大的子数组和进行返回return Math.max(maxMid(nums, left, mid, right), Math.max(maxSubArrayDivide(nums, left, mid), maxSubArrayDivide(nums, mid + 1, right)));
}private int maxMid(int[] nums, int left, int mid, int right) {int sum = 0, leftSum = Integer.MIN_VALUE, rightSum = Integer.MIN_VALUE;// 遍历[left, mid]这个范围内最大的子数组和for (int i = mid; i >= left; i--) {sum += nums[i];if (leftSum < sum) {leftSum = sum;}}sum = 0;// 遍历[mid + 1, right]这个范围内最大的子数组和for (int i = mid + 1; i <= right; i++) {sum += nums[i];if (rightSum < sum) {rightSum = sum;}}return leftSum + rightSum;
}

相关文章:

高频算法:Leetcode53 最大子数组和

今天讲的是Leetcode第53题&#xff0c;最大子数组和 首先观察题目&#xff0c;题目需要我们找出具有最大和的连续子数组&#xff0c;直接拿题目中的示例来做一个演示&#xff0c;找一找什么规律下的连续子数组才能得到最大的和 先从-2开始&#xff0c;-2 1 -1 此时我们的和…...

如何编写接口自动化测试框架、

编写接口自动化测试框架需要注意以下几点&#xff1a; 接口选择&#xff1a;首先确定需要测试的接口&#xff0c;包括请求方式、URL、参数、返回值等信息。 框架设计&#xff1a;设计一个灵活的框架&#xff0c;可以根据接口类型&#xff08;RESTful API、SOAP API等&#xff…...

【Java面试八股文宝典之RabbitMQ篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day17

大家好&#xff0c;我是陶然同学&#xff0c;软件工程大三即将实习。认识我的朋友们知道&#xff0c;我是科班出身&#xff0c;学的还行&#xff0c;但是对面试掌握不够&#xff0c;所以我将用这100多天更新Java面试题&#x1f643;&#x1f643;。 不敢苟同&#xff0c;相信大…...

ESP32开发(1)----Espressif-IDE开发环境配置

Espressif-IDE开发环境配置前言一、ESP32-WROOM-32介绍二、IDE环境搭建三、建立第一个项目总结前言 最近得到一块ESP32-WROOM-32的开发板&#xff0c;没有原理图&#xff0c;但板子走线比较简单&#xff0c;看着板子上的布线大致猜一猜连接&#xff0c;然后试玩了一下&#xf…...

MyBatisPlus标准数据层开发

MyBatisPlus标准数据层开发2&#xff0c;标准数据层开发2.1 标准CRUD使用2.2 新增2.3 删除2.4 修改2.5 根据ID查询2.6 查询所有2.7 Lombok概念使用步骤步骤1:添加lombok依赖步骤2:安装Lombok的插件步骤3:模型类上添加注解2.8 分页功能步骤1:调用方法传入参数获取返回值步骤2:设…...

C/C++每日一练(20230412)

目录 1. 二维数组找最值 &#x1f31f;&#x1f31f; 2. 排序 &#x1f31f; 3. 二叉树展开为链表 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 二维…...

Leetcode.1379 找出克隆二叉树中的相同节点

题目链接 Leetcode.1379 找出克隆二叉树中的相同节点 easy 题目描述 给你两棵二叉树&#xff0c;原始树 original和克隆树 cloned&#xff0c;以及一个位于原始树 original中的目标节点 target。 其中&#xff0c;克隆树 cloned是原始树 original的一个 副本 。 请找出在树 …...

2022年团体程序设计天梯赛-总决赛

目录 一、L1-1 今天我要赢 二、L1-2 种钻石 三、L1-3 谁能进图书馆 四、L1-4 拯救外星人 五、L1-5 试试手气 六、L1-6 斯德哥尔摩火车上的题 七、L1-7 机工士姆斯塔迪奥 八、L1-8 静静的推荐 九、L2-1 插松枝 十、L2-2 老板的作息表 十一、L2-3 龙龙送外卖 十二、L…...

大数据技术之Sqoop——SQL to Hadoop

一、简介sqoop &#xff08;sql to hadoop&#xff09;是一款开源的工具,主要用于在 Hadoop&#xff08;Hive&#xff09;与传统的数据库&#xff08;mysql、postgresql...&#xff09;间进行数据的传递&#xff0c;可以将一个关系型数据库&#xff08;例如 : MSQL,Oracle,Post…...

Java议题

序号议题 解释MyBatis官网1mapper文件中什么时候使用 # 什么时候必须用 $ 1、关键字作为参数&#xff0c;使用"$"&#xff0c;两边不加""。 2、非关键字作为参数&#xff0c;使用"#"防注入。 其他情况优先使用"#" 2主键回填&#xff0…...

【阅读论文】USAD:多变量时间序列上的无监督异常检测

USAD : UnSupervised Anomaly Detection on Multivariate Time Series 摘要 IT系统的自动监控是Orange目前面临的挑战。考虑到其IT运营所达到的规模和复杂性&#xff0c;随着时间的推移&#xff0c;用于推断正常和异常行为的测量所需的传感器数量急剧增加&#xff0c;使得传统…...

Java多线程:ReentrantLock中的方法

公平锁与非公平锁 ReentrantLock有一个很大的特点&#xff0c;就是可以指定锁是公平锁还是非公平锁&#xff0c;公平锁表示线程获取锁的顺序是按照线程排队的顺序来分配的&#xff0c;而非公平锁就是一种获取锁的抢占机制&#xff0c;是随机获得锁的&#xff0c;先来的未必就一…...

RabbitMQ初识快速入门

RabbitMQ初识&快速入门1.初识MQ1.1.同步和异步通讯1.1.1.同步通讯1.1.2.异步通讯1.2.技术对比&#xff1a;2.快速入门2.1.安装RabbitMQ2.1.1 下载镜像2.1.2 安装MQ2.2.RabbitMQ消息模型2.3.导入Demo工程2.4.入门案例2.4.1.publisher实现2.4.2.consumer实现2.5.总结1.初识MQ…...

由浅入深了解HashMap源码

由经典面试题引入&#xff0c;讲解一下HashMap的底层数据结构&#xff1f;这个面试题你当然可以只答&#xff0c;HashMap底层的数据结构是由&#xff08;数组链表红黑树&#xff09;实现的&#xff0c;但是显然面试官不太满意这个答案&#xff0c;毕竟这里有一个坑需要你去填&a…...

P5318 【深基18.例3】查找文献

题目描述 小K 喜欢翻看洛谷博客获取知识。每篇文章可能会有若干个&#xff08;也有可能没有&#xff09;参考文献的链接指向别的博客文章。小K 求知欲旺盛&#xff0c;如果他看了某篇文章&#xff0c;那么他一定会去看这篇文章的参考文献&#xff08;如果他之前已经看过这篇参考…...

Error caught was: No module named ‘triton‘

虽然报错但是不影响程序运行&#xff1a; A matching Triton is not available, some optimizations will not be enabled. Error caught was: No module named triton解决&#xff1a; pip install -i https://pypi.tuna.tsinghua.edu.cn/simple triton2.0.0.dev20221120...

Ruby设计-开发日志

Log 1 产品 Product 1.1 创建 Product 创建名为 project 的 rails 应用 rails new project创建 Product 模型 rails generate scaffold Product title:string description:text image_url:string price:decimal这会生成一个 migration &#xff0c;我们需要进一步修改这个…...

SpringBoot 调用外部接口的三种方式

方式一&#xff1a;使用原始httpClient请求 /** description get方式获取入参&#xff0c;插入数据并发起流程* params documentId* return String*/ RequestMapping("/submit/{documentId}") public String submit1(PathVariable String documentId) throws ParseE…...

C 中的结构体

C 中的结构体 C 数组允许定义可存储相同类型数据项的变量&#xff0c;结构是 C 编程中另一种用户自定义的可用的数据类型&#xff0c;它允许您存储不同类型的数据项。 结构体中的数据成员可以是基本数据类型&#xff08;如 int、float、char 等&#xff09;&#xff0c;也可以…...

nodejs安装教程

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;可以用于在服务器端运行 JavaScript 代码。以下是 Node.js 的安装教程&#xff1a; 步骤 1&#xff1a;下载 Node.js 访问 Node.js 的官方网站 https://nodejs.org/&#xff0c;进入官方下载页面。 在下载页…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

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

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

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...