最大子数组和

GitHub跳转原题关系图返回列表

Kadane 算法:以 i 结尾的最大和 = max(a[i], dp[i-1] + a[i]),滚动 O(1) 空间。

OJ: leetcodecn

题目 ID: maximum-subarray

难度:普及+/提高

标签:数组动态规划分治cpppython

日期: 2026-07-28 22:05

题意

整数数组 nums,找出和最大的连续子数组,返回其和。

思路

暴力枚举 O(n²)。Kadane 算法:dp[i] 表示以 i 结尾的子数组最大和,转移 dp[i] = max(a[i], dp[i-1] + a[i])。由于只依赖前一个状态,可用一个变量滚动。

全负数组不影响算法正确性,因为每个位置至少可以选自己。

代码

cpp
/**
 * Author by Rainboy
 */
// main.cpp:Kadane 算法,dp[i] = max(a[i], dp[i-1] + a[i]),O(n)。
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    int maxSubArray(vector<int> &nums) {
        int ans = nums[0], cur = nums[0];
        for (size_t i = 1; i < nums.size(); i++) {
            cur = max(nums[i], cur + nums[i]);
            ans = max(ans, cur);
        }
        return ans;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n);
    for (int &x : a)
        cin >> x;
    cout << Solution().maxSubArray(a) << '\n';
    return 0;
}
python
#!/usr/bin/env python3
from typing import List


class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        ans = cur = nums[0]
        for x in nums[1:]:
            cur = max(x, cur + x)
            ans = max(ans, cur)
        return ans


def main() -> None:
    n = int(input())
    nums = list(map(int, input().split()))
    print(Solution().maxSubArray(nums))


if __name__ == "__main__":
    main()

复杂度

  • 时间复杂度:O(n),一次遍历。
  • 空间复杂度:O(1)。

总结

Kadane 算法是"线性 DP 滚动"的经典例子。把"枚举所有子数组"降维成"枚举所有结尾位置",每个结尾只需维护以该位置结尾的最大值。