当前位置: 首页 > 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;进入官方下载页面。 在下载页…...

Go语言开源漏洞扫描器Abyss-Scanner:架构解析与CI/CD集成实践

1. 项目概述&#xff1a;一个为安全而生的开源漏洞扫描器最近在整理自己的开源项目工具箱&#xff0c;发现一个挺有意思的工具&#xff0c;叫 Abyss-Scanner。这名字起得挺有深意&#xff0c;“深渊扫描器”&#xff0c;听起来就有点探索未知、发现潜在风险的味道。简单来说&am…...

Performance-Fish:深度解析《环世界》400%性能优化核心技术

Performance-Fish&#xff1a;深度解析《环世界》400%性能优化核心技术 【免费下载链接】Performance-Fish Performance Mod for RimWorld 项目地址: https://gitcode.com/gh_mirrors/pe/Performance-Fish Performance-Fish 是专为《环世界》&#xff08;RimWorld&#…...

解锁你的音乐宝藏:ncmdump让网易云音乐文件自由播放

解锁你的音乐宝藏&#xff1a;ncmdump让网易云音乐文件自由播放 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 当你精心收藏的网易云音乐只能在特定客户端播放时&#xff0c;那种被束缚的感觉是否让你感到无奈&#xff1f;想象一下…...

【实战指南】STM32CubeMX UART配置进阶:从阻塞到中断+DMA的高效数据通信

1. UART通信模式选择指南 第一次接触STM32的UART通信时&#xff0c;很多人都会纠结该用哪种模式。我在实际项目中尝试过所有模式&#xff0c;总结下来就是&#xff1a;没有最好的模式&#xff0c;只有最适合当前场景的模式。先说说三种典型场景&#xff1a; 调试打印&#xff1…...

DriveBench:面向真实驾驶场景的长序列多智能体交互基准测试框架

1. 项目概述&#xff1a;从“世界基准”到“驾驶基准”的演进如果你在自动驾驶或者计算机视觉领域摸爬滚打过几年&#xff0c;一定对“基准测试”&#xff08;Benchmark&#xff09;这个词又爱又恨。爱的是&#xff0c;它提供了一个相对公平的擂台&#xff0c;让不同算法、不同…...

5分钟免费获取:开源鼠标连点器MouseClick完整使用指南

5分钟免费获取&#xff1a;开源鼠标连点器MouseClick完整使用指南 【免费下载链接】MouseClick &#x1f5b1;️ MouseClick &#x1f5b1;️ 是一款功能强大的鼠标连点器和管理工具&#xff0c;采用 QT Widget 开发 &#xff0c;具备跨平台兼容性 。软件界面美观 &#xff0c;…...

【最新v2.7.1 版本安装包】OpenClaw 小白入门必看,零基础无需命令零代码保姆级教学

OpenClaw v2.7.1 一键安装部署教程&#xff5c;可视化傻瓜式搭建 ✨适配系统&#xff1a;Windows10/11 64 位 ✨当前版本&#xff1a;v2.7.1 版本&#xff08;虾壳云版&#xff09; ✨安装包大小&#xff1a;58.7MB 【点击下载最新安装包】https://xiake.yun/api/download/…...

Flutter桌面端窗口控制:从隐藏标题栏到自定义全屏交互

1. 为什么需要自定义窗口控制&#xff1f; 当你用Flutter开发Windows桌面应用时&#xff0c;系统默认的标题栏和窗口样式往往显得格格不入。想象一下&#xff0c;你精心设计了一套深色主题的UI&#xff0c;结果顶部突然冒出一条灰白色的标准标题栏——就像给西装革履的绅士戴了…...

RL78/G13单片机实现流水呼吸灯:软件PWM与状态机编程实践

1. 项目概述与核心思路最近在整理手头的瑞萨RL78/G13开发板&#xff0c;想着做点有意思的小项目来熟悉一下这款MCU的GPIO操作和定时器资源。呼吸灯和流水灯算是嵌入式开发的“Hello World”了&#xff0c;但把两者结合起来&#xff0c;做成一个“流水呼吸灯”&#xff0c;既有动…...

Linux系统信息查询全攻略:从内核到发行版的深度解析与脚本实践

1. 项目概述&#xff1a;一个看似简单却暗藏玄机的基础操作“查看Linux系统版本”&#xff0c;这几乎是每个运维工程师、开发人员乃至普通用户在接触Linux系统时&#xff0c;第一个需要掌握的命令。它简单到常常被新手教程一笔带过&#xff0c;却又复杂到足以让老手在排查问题时…...