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

力扣hot100:最大子数组和的两种高效方法:前缀和与Kadane算法(53)

最大子数组和问题是算法中的一个经典问题,即在给定整数数组中寻找连续子数组使其和达到最大(子数组不能为空)。本文将详细解析两种时间复杂度为 O(n)、空间复杂度为 O(1) 的精妙解法,并附上完整 Java 实现。

问题示例

给定数组 [-2,1,-3,4,-1,2,1,-5,4],最大子数组和为 [4,-1,2,1],其和为 6

方法一:前缀和法(Prefix Sum)

核心思想

通过动态计算数组前缀和,并维护当前最小前缀和,用当前前缀和减去最小前缀和得到局部最大子数组和。

算法步骤
  1. 初始化 temp 为当前前缀和(初始值为0)
  2. 初始化 min 为最小前缀和(初始值为0)
  3. 遍历数组:
    • 更新当前前缀和 temp += num
    • 计算当前子数组和:temp - min
    • 更新全局最大值 result
    • 更新最小前缀和 min
public int maxSubArrayT1(int[] nums) {int temp = 0;int min = 0;int result = Integer.MIN_VALUE;for (int num : nums) {temp += num;             // 更新当前前缀和result = Math.max(result, temp - min); // 更新全局最大值min = Math.min(temp, min);    // 更新最小前缀和}return result;
}
示例分析

[-2,1,-3] 为例:

步骤numtempmintemp-minresult
初始-00-MIN
1-2-2-2-2-0=-2-2
21-1-2-1-(-2)=11
3-3-4-4-4-(-2)=-21(保持)

方法二:Kadane算法(动态规划)

核心思想

通过动态维护当前连续子数组和,当和小于等于0时丢弃该子数组(因其无法增大后续和),同时全程更新最大值。

算法步骤
  1. 初始化 temp 为当前子数组和(初始值为0)
  2. 初始化 max 为全局最大值(初始值为 Integer.MIN_VALUE
  3. 遍历数组:
    • temp += nums[i](累加当前值)
    • 更新 max = Math.max(max, temp)
    • 若 temp <= 0,重置 temp = 0(丢弃负贡献子数组)
public int maxSubArrayT2(int[] nums) {int max = Integer.MIN_VALUE;int temp = 0;for (int num : nums) {temp += num;          // 累加当前值max = Math.max(max, temp);  // 更新全局最大值if (temp <= 0) temp = 0;    // 若和为负则重置}return max;
}

示例分析

[-2,1,-3] 为例:

步骤numtempmax操作
初始-0MIN-
1-2-2-2temp<=0 → 重置为0
210+1=1max(-2,1)=1-
3-31-3=-2max(1,-2)=1temp<=0 → 重置为0

方法对比与总结

特性前缀和法Kadane算法
核心思想前缀和与最小值差值动态丢弃负和子数组
重置条件无显式重置当 temp<=0 时重置
适用场景需处理前缀和问题时标准最大子数组问题
优势直观易扩展代码更简洁

关键共同点

  • 时间复杂度 O(n)(只需一次遍历)
  • 空间复杂度 O(1)(仅用常数变量)
  • 均能正确处理全负数数组(如 [-3,-1,-2] 返回 -1

两种方法都是高效解法,在实际面试或解题中:

  • Kadane算法更简洁常用
  • 前缀和法在需复用前缀信息时更灵活(如解决子矩阵最大和等问题)

两种解法简洁优雅,体现了算法设计中“维护关键状态,避免重复计算”的核心思想。理解其内在逻辑后,你能轻松应对各类子数组相关问题!

http://www.xdnf.cn/news/18458.html

相关文章:

  • 学习设计模式《二十三》——桥接模式
  • uniapp:h5链接拉起支付宝支付
  • 有向图(Directed Graph)和有向无环图(Directed Acyclic Graph,DAG)代码实践
  • pcl求平面点云的边界凸包点
  • 池化技术分析
  • GISBox工具:FBX到3DTiles文件转换指南
  • Eclipse 里Mybatis的xml的头部报错
  • 仿真驱动的AI自动驾驶汽车安全设计与测试
  • JVM基础知识总结
  • 深入解析FTP核心术语03
  • PWA》》以京东为例安装到PC端
  • 从二进制固件到人类意识:AI小智开发全记录与技术沉思—— 一个创客的硬件实践与认知边界探索
  • 数据预处理
  • 怎么确定mongodb是不是链接上了?
  • 电脑驱动免费更新? 这款驱动管理工具:一键扫更新,还能备份恢复,小白也会用~
  • 嵌入式音频开发(3)- AudioService核心功能
  • uniapp开发微信小程序自定义导航栏
  • K距离间隔重排字符串 (LeetCode 358) — Swift解法 + 可运行Demo
  • 嵌入式开发学习———Linux环境下网络编程学习(四)
  • 计算机网络基础复习
  • 鸿蒙安卓前端中加载丢帧:ArkWeb分析
  • (5)软件包管理器 yum | Vim 编辑器 | Vim 文本批量化操作 | 配置 Vim
  • K8S-Pod资源对象
  • Electron开发的核心功能要点总结,旨在帮助快速掌握Electron开发核心逻辑
  • 用TestComplete打造高效CI/CD测试流程
  • 计算机网络技术-局域网配置(Day.4)
  • 车联网(V2X)中万物的重新定义---联网汽车新时代
  • 算法第五十二天:图论part03(第十一章)
  • 【图论】拓扑排序
  • 【考研408数据结构-09】 图论进阶:最短路径与最小生成树