LeetCode53. Maximum Subarray(剑指offer42题)

这篇博客探讨了如何解决寻找整数数组中具有最大和的连续子数组的问题。文章介绍了两种解决方案:动态规划(Kadane's Algorithm)和分治法,并详细解释了每种方法的思路。动态规划法具有O(n)的时间复杂度,而分治法通过递归处理数组的左右半部分并结合中间元素来寻找最大子数组。博客还提到了Kadane's Algorithm的实现细节和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

Follow up:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.


solution1 optimization problem -DP

  • optimization problem -DP
    1. the format of the sub problem(or the state of each sub problem).
    2. recursive
maxSubArray(A, i) = maxSubArray(A, i - 1) > 0 ? maxSubArray(A, i - 1) : 0 + A[i]; 

动态规划。用循环做。
F(i)=numsi;
F(i)=nums[i]+F(i-1)(F(i-1)>0)
细节:nums只有{-1}时,所以开始sum=nums[0],然后从第二个开始循环。

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
        if(array.empty())
            return 0;
        int cur=array[0];
        int max=cur;
        for(auto it = array.begin()+1;it!=array.end();it++)
        {
            if(cur<=0)
            {
                cur = *it;
            }
            else
            {
                cur+=*it;
            }
            if(cur>max)
            {
                max=cur;
            }
        }
    return max;
    }
};

solution2 Divide-and-Conquer

  • The Divide-and-Conquer algorithm breaks nums into two halves and find the maximum subarray sum in them recursively.
  • the maximum subarray spans the two halves.
  • a linear algorithm: starting from the middle element and move to both ends (left and right ends), record the maximum sum we have seen. In this case, the maximum sum is finally equal to the middle element plus the maximum sum of moving leftwards and the maximum sum of moving rightwards.
  • Since we are done with LHS and RHS, we only need to check the case where we pass the middle element.(i.e. the middle element must be included).In that case, since our question asks a continuous subset, it must expand that way.

分治法。2*O(n/2)+O(1)=O(n)

  • divide:用递归来分别求左右子集的max
  • merge:用dp来从左右分别线性探索,加上mid
  • 最后找到divide和merge中最大的就是要求的值。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        return maxSubArray(nums, 0, nums.size() - 1);
    }
private:
    int maxSubArray(vector<int>& nums, int l, int r) {
        if (l > r) {
            return INT_MIN;
        }

        //divide:
        int m = l + (r - l) / 2;
        int lmax = maxSubArray(nums, l, m - 1);//left
        int rmax = maxSubArray(nums, m + 1, r);//right
        int partmax = max(lmax, rmax);//not including mid
        
        //Merge:
        int ml= 0,mr = 0;
        //left-DP:O(n/2)
        for (int i = m - 1, sum = 0; i >= l; i--) {
            sum += nums[i];
            ml = max(sum, ml);
        }
        //right-DP:O(n/2)
        for (int i = m + 1, sum = 0; i <= r; i++) {
            sum += nums[i];
            mr = max(sum, mr);
        }
        //Merge-including mid,for continuous subset:O(1)
        int contmax=ml + mr + nums[m];

        return max(partmax,contmax);
        //2*O(n/2)+O(1)=O(n)
    }
};

Kadane’s algorithm

  • Aka Maximum Sum of Subarray
  • Dynamic Programming

Maximum Subarray Problem

From Wikipedia

In computer science, the maximum subarray problem is the task of finding the contiguous subarray within a one-dimensional array, a[1…n], of numbers which has the largest sum.

The task is to find a subarray (contiguous elements) of the given array that has the largest sum. For instance:

[1, 5, -1, 0, 10]

The answer would be 15 or the entire array (it’s also a subarray)

[0, -1, -5, 0, -4]

The answer would be 0 and so on.

Solutions

Brute-force

All you need is going through all sub-arrays, keep the global maximum and compare.

Dynamic Programming (Kadane’s Algorithm)

  • O(n) runtime complexity
  • O(1) space.

Following function shows the Kadane’s algorithm implementation which uses two variables, one to store the local maximum and the other to keep track of the global maximum:

def max_subarray(A):
    max_ending_here = max_so_far = A[0]
    for x in A[1:]:
        max_ending_here = max(x, max_ending_here + x)
        max_so_far = max(max_so_far, max_ending_here)
    return max_so_far

So we assume that the largest subarray is the first element, then we go through A[1:] elements (all elements except the first one).

At each step, what we do is:

  • Can current element plus the last largest sum_ help to find a largest subarray (line 4)?
  • If yes, update the max_ending_here or our local maximum, otherwise current element is the largest subarray (array of one).
  • Then update the global maximum or max_so_far if there is a new global maximum.

When the loop is over, return the global maximum.

Conclusion

Kadane’s algorithm is a Dynamic Programming approach to solve “the largest contiguous elements in an array” with runtime of O(n).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值