当前位置: 首页 > 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.lryc.cn/news/626930.html

相关文章:

  • Deepseek+python自动生成禅道测试用例
  • 自动化测试用例生成:基于Python的参数化测试框架设计与实现
  • 记一次pnpm start启动异常
  • Spring Boot 3整合Nacos,配置namespace
  • 质谱数据分析环节体系整理
  • Rust 入门 包 (二十一)
  • 内网环境给VSCode安装插件
  • PostgreSQL 流程---更新
  • 基于51单片机自动浇花1602液晶显示设计
  • Notepad++批量转UTF-8脚本
  • 测试DuckDB插件对不同格式xlsx文件的读写效率
  • 基于Pytochvideo训练自己的的视频分类模型
  • 【C++】基础:C++11-14-17常用新特性介绍
  • XR(AR/VR/MR)芯片方案,Soc VS “MCU+协处理器”?
  • 109、【OS】【Nuttx】【周边】效果呈现方案解析:workspaceStorage(下)
  • 【最后203篇系列】034 使用SQLite构建简单的任务管理
  • 解决Docker 无法连接到官方镜像仓库
  • LINUX 820 shell:shift,expect
  • 49 C++ STL模板库18-类模板-pair
  • 双模式 RTMP H.265 播放器解析:从国内扩展到 Enhanced RTMP 标准的演进
  • 深入理解JVM内存结构:从字节码执行到垃圾回收的全景解析
  • 基于单片机智能加湿器/空气加湿器
  • ubuntu系统上的conda虚拟环境导出方便下次安装
  • 计算机毕设Spark项目实战:基于大数据技术的就业数据分析系统Django+Vue开发指南
  • Typescript入门-数组元组讲解
  • CSS3DRenderer+ CSS3DObject实现在 Three.js 中添加文本内容
  • 监听视频是否加载完毕
  • 次短路P2865 [USACO06NOV] Roadblocks G题解
  • KubeBlocks for ClickHouse 容器化之路
  • 【机器学习深度学习】AI大模型高并发挑战:用户负载部署策略