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

力扣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.dtcms.com/a/341173.html

相关文章:

  • 【数据结构】递归与非递归:归并排序全解析
  • CreateRef和useRef
  • 继续记事本项目
  • 三轴云台之闭环反馈技术
  • MySQL数据库安全配置核心指南
  • 十二,数据结构-链表
  • BeyondWeb:大规模预训练合成数据的启示
  • 解决程序无响应自动重启
  • 高压柜无线测温:给智能化配电室装上“智能体温监测仪”
  • 前端基础知识操作系统系列 - 03(linux系统下 文件操作常用的命令有哪些)
  • C++ string(reserve , resize , insert , erase)
  • Clonezilla live 再生龙还原系统各个版本的不同
  • Sklearn 机器学习 房价预估 拆分训练集和测试集
  • Pydantic介绍(基于Python类型注解的数据验证和解析库)(BaseModel、校验邮箱校验EmailStr、BaseSettings)
  • SeaweedFS深度解析(五):裸金属集群部署(上)
  • Java 集合超详细教程
  • 循环神经网络(RNN)、LSTM 与 GRU (一)
  • 基于深度学习的订单簿异常交易检测与短期价格影响分析
  • 【深度学习】PyTorch中间层特征提取与可视化完整教程:从零开始掌握Hook机制与特征热力图
  • lua入门以及在Redis中的应用
  • 【ElasticSearch实用篇-03】QueryDsl高阶用法以及缓存机制
  • Java程序启动慢,DNS解析超时
  • 基于STM32的APP遥控视频水泵小车设计
  • K8S-Pod资源对象——标签
  • 【AI学习100天】Day08 使用Kimi每天问100个问题
  • 【指纹浏览器系列-绕过cdp检测】
  • 数据预处理:机器学习的 “数据整容术”
  • nginx-下载功能-状态统计-访问控制
  • 【数据结构】线性表——顺序表
  • 循环神经网络(RNN, Recurrent Neural Network)