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

力扣第五十三题——最大子数组和

内容介绍

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组

是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

完整代码

 int maxSubArray(int* nums, int numsSize) {int pre = 0, maxAns = nums[0];for (int i = 0; i < numsSize; i++) {pre = fmax(pre + nums[i], nums[i]);maxAns = fmax(maxAns, pre);}return maxAns;
}

思路详解

一、问题背景

给定一个整数数组,要求找到数组中的最大子数组和。所谓最大子数组和,是指数组中一个或多个连续元素组成的子数组,其元素之和最大。

二、解题思路

  1. 动态规划

    • 使用动态规划的思想,通过遍历数组,记录当前位置之前所有可能的子数组和,从而找到最大的子数组和。
  2. 状态定义

    • 定义一个变量pre来记录当前遍历到当前位置之前所有可能的子数组和的最大值。
    • 初始时,pre为0,因为第一个元素本身就是最大的子数组和。
  3. 状态转移

    • 在遍历数组的过程中,对于每个元素,我们有两个选择:
      • 将当前元素与之前的子数组和pre相加,形成一个新的子数组和。
      • 只考虑当前元素,形成一个新的子数组和。
    • 我们选择这两个子数组和中的较大者作为新的pre
  4. 结果记录

    • 在遍历过程中,我们需要记录pre中的最大值,即当前找到的最大子数组和。
    • 最终返回这个最大值。

三、代码详解

  1. 初始化
    • 初始化pre为0,表示当前还没有开始遍历数组。
    • 初始化maxAns为数组的第一个元素,因为至少包含一个元素的子数组和的最大值就是数组的第一个元素。
int pre = 0, maxAns = nums[0];
  1. 遍历数组
    • 遍历数组中的每个元素。
    • 对于每个元素,计算两种情况下的子数组和,并取较大者作为新的pre
    • 同时更新maxAnspremaxAns中的较大者。
for (int i = 0; i < numsSize; i++) {pre = fmax(pre + nums[i], nums[i]);maxAns = fmax(maxAns, pre);
}
  1. 返回结果
    • 遍历结束后,maxAns中存储的就是数组中的最大子数组和。
    • 返回maxAns
return maxAns;

四、总结

通过动态规划的思想,我们能够高效地找到数组中的最大子数组和。关键在于维护当前遍历到当前位置之前所有可能的子数组和的最大值,并在遍历过程中不断更新这个值。这种方法的时间复杂度为O(n),空间复杂度为O(1),因为只需要常数级别的额外空间。

知识点精炼

一、核心概念

  1. 动态规划:一种通过保存中间结果来避免重复计算的算法设计技巧。
  2. 状态转移:在动态规划中,每个状态都是基于前一个状态计算得出的。
  3. 贪心算法:一种在每一步选择中都采取当前状态下最优(即看起来最有利)的选择,从而希望导致全局最优解的算法。

二、知识点精炼

  1. 最大子数组和问题

    • 要求在数组中找到一个子数组,其元素之和最大。
  2. 动态规划解法

    • 使用一个变量pre来记录从数组开始到当前位置的所有可能的子数组和的最大值。
    • 在遍历数组的过程中,更新pre为当前元素与pre相加的和以及当前元素的较大者。
  3. 状态转移

    • 在遍历数组的过程中,对于每个元素,有两种选择:
      • 将当前元素与之前的子数组和pre相加,形成一个新的子数组和。
      • 只考虑当前元素,形成一个新的子数组和。
    • 选择这两种子数组和中的较大者作为新的pre
  4. 结果记录

    • 在遍历过程中,记录pre中的最大值,即当前找到的最大子数组和。
    • 最终返回这个最大值。

三、性能分析

  • 时间复杂度:O(n),因为需要遍历数组一次。
  • 空间复杂度:O(1),只需要常数级别的额外空间。

四、实际应用

  • 数据处理:在处理大量数据时,动态规划可以帮助我们找到最优解,从而提高效率。
  • 算法竞赛:在算法竞赛中,掌握动态规划对于解决组合优化问题非常有帮助。

五、代码实现要点

  • 初始化:正确初始化premaxAns变量。
  • 遍历数组:在遍历数组的过程中,正确更新premaxAns变量。
  • 返回结果:在遍历结束后,正确返回maxAns变量。

 动态规划的其他应用场景

  1. 最长公共子序列(LCS)

    • 在两个或多个序列中找到最长的公共子序列,例如在文本编辑器中找到两个文本文件之间的差异。
  2. 最短路径问题

    • 在图论中,动态规划可以用于解决最短路径问题,例如Dijkstra算法和Floyd-Warshall算法。
  3. 背包问题

    • 在计算机科学中,背包问题是指给定一组物品和背包容量,如何选择物品放入背包以获得最大价值。
  4. 字符串匹配

    • 使用动态规划解决字符串匹配问题,如KMP算法,它可以高效地找到一个字符串在另一个字符串中出现的次数。
  5. 矩阵链乘法

    • 动态规划可以用来找到矩阵连乘的最优顺序,以最小化乘法运算的总次数。
  6. 最长递增子序列(LIS)

    • 在数组中找到最长递增子序列的长度,例如在股票市场中找到最长的连续增长期。
  7. 编辑距离

    • 动态规划可以用来计算两个字符串之间的编辑距离,即通过插入、删除和替换字符来将一个字符串转换为另一个字符串的最少操作次数。
  8. 最优二叉搜索树

    • 动态规划可以用来构建最优二叉搜索树,即权值分配给节点,使得树的总权重最小。
  9. 股票买卖问题

    • 在股票市场中,动态规划可以用来解决如何在多次交易中最大化利润的问题。
  10. 硬币找零问题

    • 给定不同面值的硬币和需要找零的金额,动态规划可以用来找到找零的最少硬币数量。

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 如何开始学习Swift编程?
  • MySQL 实战 45 讲(01-05)
  • C# udp通信测试助手
  • 【数据分享】2024最新安徽省镇级行政区划矢量shp
  • 【面试经验】京东java京东young 一面80min
  • 电子元器件—三极管(一篇文章搞懂电路中的三极管)(笔记)(面试考试必备知识点)
  • EMQX服务器安装MQTT测试
  • 通过Netlink检测USB设备的插拔
  • 吴恩达老师机器学习作业-ex7(聚类)
  • 使用 Ansible Blocks 进行错误处理
  • Centos服务器root用户禁止远程登录
  • Html5总结
  • Node.js(8)——Express的基本使用
  • Opencv调用yolov5的onnx文件时报错记录
  • B站宋红康JAVA基础视频教程个人笔记chapter03
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • css系列之关于字体的事
  • export和import的用法总结
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 简单数学运算程序(不定期更新)
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 删除表内多余的重复数据
  • 跳前端坑前,先看看这个!!
  • 微服务框架lagom
  • 用简单代码看卷积组块发展
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • (3)(3.5) 遥测无线电区域条例
  • (zhuan) 一些RL的文献(及笔记)
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (佳作)两轮平衡小车(原理图、PCB、程序源码、BOM等)
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (十五)使用Nexus创建Maven私服
  • ****Linux下Mysql的安装和配置
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .net core + vue 搭建前后端分离的框架
  • .net 获取url的方法
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .Net插件开发开源框架
  • .sh 的运行
  • /proc/interrupts 和 /proc/stat 查看中断的情况
  • @RequestBody与@RequestParam:Spring MVC中的参数接收差异解析
  • [ C++ ] STL_vector -- 迭代器失效问题
  • [Android Studio 权威教程]断点调试和高级调试
  • [Android]Android开发入门之HelloWorld
  • [ASP.NET MVC]Ajax与CustomErrors的尴尬
  • [C/C++入门][ifelse]20、闰年判断
  • [C++初阶]string类的详解
  • [C++进阶]map和set的相关题目
  • [ComfyUI]Flux+MiniCPM-V强强联手艺术创意,媲美GPT4V级国产多模态视觉大模型
  • [EMWIN]FRAMEWIN 与 WINDOW 的使用注意
  • [G-CS-MR.PS02] 機巧之形2: Ruler Circle