LeetCode算法刷题——53. 最大子数组和

一、题目描述

二、解题思路

我们使用前缀和的思想来高效解决这个问题:

  1. 计算当前位置的前缀和sum(到当前元素为止的总和)

  2. 用当前前缀和减去之前的最小前缀和minpre,得到以当前位置结尾的子数组最大和

  3. 比较sum和premin,更新最小前缀和变量

  4. 记录过程中的最大子数组和

三、完整代码

class Solution {

public:

int maxSubArray(vector<int>& nums) {

int sum = 0; // 当前前缀和

int result = INT_MIN; // 最大子数组和,初始化为最小整数

int minpre = 0; // 最小前缀和

for(int i = 0; i < nums.size(); i++) {

// 更新当前前缀和

sum = sum + nums[i];

// 用当前前缀和减去最小前缀和,更新最大和

result = max(result, sum - minpre);

// 更新最小前缀和(用于后续计算)

minpre = min(sum, minpre);

}

return result;

}

};

四、代码解析

1. 变量初始化

int result = INT_MIN;

  • 使用 **INT_MIN**确保即使全是负数也能正确处理

  • 这个值是 <climits> 中定义的,代表最小整数

2. 核心思想:最小前缀和

result = max(result, sum - minpre);

  • 关键原理:最大子数组和 = 当前前缀和 - 之前的最小前缀和

  • 如果我们在位置 i 有前缀和 sum[i],在位置 j (j < i) 有前缀和 sum[j]

  • 那么子数组 nums[j+1...i] 的和 = sum[i] - sum[j]

  • 要使子数组值最大,就需要找到最小的 sum[j],即之前的最小前缀和

3. 更新最小前缀和

minpre = min(sum, minpre);

  • 在计算完当前结果后,更新最小前缀和

  • 这样可以确保下次计算时使用的是当前之前的最小前缀和

  • 初始时 minpre = 0,对应空子数组(前缀和为0)

五、执行示例

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]

详细步骤:

i nums[i] sum minpre sum-minpre result
0 -2 -2 0 -2-0=-2 -2
1 1 -1 -2 -1-(-2)=1 1
2 -3 -4 -4 -4-(-4)=0 1
3 4 0 -4 0-(-4)=4 4
4 -1 -1 -4 -1-(-4)=3 4
5 2 1 -4 1-(-4)=5 5
6 1 2 -4 2-(-4)=6 6
7 -5 -3 -4 -3-(-4)=1 6
8 4 1 -4 1-(-4)=5 6

最终结果:6(对应子数组 [4,-1,2,1])

六、总结

本文介绍了使用前缀和和最小前缀思想求解最大子数组和的高效算法。该算法的核心在于:最大子数组和等于当前前缀和减去之前的最小前缀和。通过维护一个最小前缀和变量,我们可以在一次遍历中解决问题,时间复杂度O(n),空间复杂度O(1)。这种方法比暴力法的O(n²)和分治法的O(n log n)都要高效,是解决最大子数组和问题的最优解法。

相关推荐
颜酱2 小时前
二叉树分解问题思路解题模式
javascript·后端·算法
码路飞4 小时前
GPT-5.3 Instant 终于学会好好说话了,顺手对比了下同天发布的 Gemini 3.1 Flash-Lite
java·javascript
qianpeng8974 小时前
水声匹配场定位原理及实验
算法
SimonKing4 小时前
OpenCode AI编程助手如何添加Skills,优化项目!
java·后端·程序员
Seven976 小时前
剑指offer-80、⼆叉树中和为某⼀值的路径(二)
java
董董灿是个攻城狮15 小时前
AI视觉连载8:传统 CV 之边缘检测
算法
怒放吧德德17 小时前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆19 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
心之语歌21 小时前
基于注解+拦截器的API动态路由实现方案
java·后端
blasit1 天前
笔记:Qt C++建立子线程做一个socket TCP常连接通信
c++·qt·tcp/ip