最大子段和标准解法是单次扫描,用current = max(nums[i], current + nums[i])更新以i结尾的最大和,best记录全局最大值;current和best均初始化为nums[0],避免全负数或溢出错误。

最大子段和的标准解法:用 std::max 迭代更新
核心就是一遍扫描,边走边记“以当前位置结尾的最大子段和”。不需要二维数组,更不需枚举所有子段——那会是 O(n²) 甚至 O(n³)。
关键逻辑:到位置 i 时,要么把前面的子段接上(如果它还大于 0),要么从 i 重新开始。所以状态转移就是:current = std::max(nums[i], current + nums[i])。
常见错误现象:current 初始化成 0,结果全负数时返回 0(错!应返回最大那个负数);或漏更新全局最大值 best。
-
current和best都该初始化为nums[0],不是 0 - 循环从
i = 1开始,避免重复计算nums[0] - 别用
INT_MIN初始化——如果输入含INT_MIN自身,比较会出问题;直接用首元素最稳
为什么不用 vector<int> 存 DP 表?
因为状态只依赖前一个值,存整个数组纯属浪费空间。C++ 里多开一维 dp[i] 不仅内存翻倍,缓存局部性还差,对大数组(比如 1e6 元素)影响明显。
立即学习“C++免费学习笔记(深入)”;
实际场景中,LeetCode 或 OJ 的测试用例常卡空间限制;本地跑大数据时,栈上分配大 vector 可能直接 std::bad_alloc。
- DP 空间优化是强制项,不是可选项
- 如果题目后续要输出子段区间(不只是和),只需额外记两个下标变量:
start、end,不增加空间复杂度 - 别为了“看着像 DP”硬写
vector——面试官一眼看出没理解本质
遇到 long long 溢出怎么办?
原题数据范围没说,但实际输入可能含大整数或超长序列。用 int 累加,中间值溢出后结果完全不可信,且不会报错,极难调试。
典型表现:小样例全对,一换大数据就答案偏差;或与 Python 脚本比对时发现不一致。
- 只要题目没明确限定“所有数在 int 范围内”,默认用
long long声明current和best -
nums是vector<int>没关系,赋值时自动提升,关键是累加器类型 - 别用
auto current = nums[0]——推导出int,隐患埋得深
边界情况:空数组和单元素怎么处理?
标准题干一般保证非空,但工程代码或自测时必须考虑。C++ 里传空 vector 进函数,nums[0] 是未定义行为,nums.empty() 必须先判。
单元素看似简单,但和初始化逻辑强耦合——如果初始化写成 best = 0,单负数就挂。
- 开头加
if (nums.empty()) return 0;(按业务约定,也可抛异常) - 单元素数组自然被
best = nums[0]覆盖,无需特殊分支 - 别依赖“测试数据肯定不空”——CI 流水线跑单元测试时,空输入是第一道过滤器











