← 所有笔记

算法训练 leetcode hot 100 53 最大子数组和

一道最大子数组和,两种解题视角。用动态规划与分治理解状态、边界和问题的拆解。

题目链接

53. 最大子数组和

题目描述

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

提示:

  • 1 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4

**进阶:**如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

分析及AC代码

好简单的dp,无需多言

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

再思考一下进阶的分治做法

感觉用分治写有点多此一举,就当锻炼思维了。核心在于 可以将 区间分为 左区间,右区间,还有一个跨区间。左区间和右区间的起点和终点容易确定。中间跨区间由中心向两边枚举即可。时间复杂度 O(nlogn) ,比 dp 的O(n) 更久。

class Solution {
public:
    int find_max(int l, int r, vector<int>& nums) {
        if (l == r) {
            return nums[l];
        }
        if (r - l + 1 == 2) {
            return max(max(nums[l], nums[r]), nums[l] + nums[r]);
        }
        int mid = (l + r) >> 1;
        int l_subarr_max = find_max(l, mid, nums);
        int r_subarr_max = find_max(mid, r, nums);
        int across_max = nums[mid];
        int l_p = mid - 1, r_p = mid + 1;
        int l_sum = nums[l_p], r_sum = nums[r_p];
        int l_max = l_sum, r_max = r_sum;
        while (l_p > l) {
            l_p--;
            l_sum += nums[l_p];
            l_max = max(l_max, l_sum);
        }
        while (r_p < r) {
            r_p++;
            r_sum += nums[r_p];
            r_max = max(r_max, r_sum);
        }
        across_max = across_max + l_max + r_max;
        return max(across_max, max(l_subarr_max, r_subarr_max));
    }

    int maxSubArray(vector<int>& nums) {
        return find_max(0, nums.size() - 1, nums);
    }
};
✳

谢谢你读到这里。

更新于 2025-12-28

搜索笔记

搜索文章标题、标签和正文。

↑ ↓ 选择 · Enter 阅读Esc 关闭