LeetCode 53. Maximum Subarray 题解

来源:互联网 发布:ps淘宝详情页模板 编辑:程序博客网 时间:2024/05/16 03:17

最大子序列和问题

【题目】

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

 For example, given the array [-2,1,-3,4,-1,2,1,-5,4], the contiguous subarray [4,-1,2,1] has the largest sum = 6.

题解

最大子序列和有多种解法,最简单的一种是遍历所有子序列,代码如下:

    int maxSubArray(vector<int>& nums) {        int maxSum = INT_MIN;          for(int i = 0; i < nums.size(); i++) {               for(int j = i; j < nums.size(); j++) {                   int nSum = 0;                  for(int k=i; k<=j; k++)                    nSum += nums[k];                                if(nSum > maxSum)                    maxSum = nSum;             }          }          return maxSum;           }

可看到代码中有三层循环嵌套,故其时间复杂度为O(n^3),同时,包含了很多重复的计算,效率很低,在LeetCode上提交会有Time Limit Exceeded的错误。

优化的办法很容易想到,我们只需遍历从起始位置开始的子序列就行了,代码如下:

    int maxSubArray(vector<int>& nums) {        int nSize = nums.size();        if (nSize == 0)            return 0;                int maxSum = INT_MIN;          for(int i = 0; i < nSize; i++) {            int nSum = 0;            for(int j = i; j < nSize; j++) {                nSum += nums[j];                if(nSum > maxSum)                    maxSum = nSum;             }          }          return maxSum;           }

       其时间复杂度我们降到了O(n^2),虽然在LeetCode上提交可以得到Accept,但如果仔细观察的话会发现可以进一步改进。

        假如起始位置的值为负,显然不是最大子序列和的起始点,一种特殊情况除外,即序列所有的值均为负数,这时我们只需要找到最大的负数即可。从负数不为最大子序列和的起点出发,我们可以得到下列代码:

    int maxSubArray(vector<int>& nums) {        int nSize = nums.size();        if (nSize == 0)            return 0;                int maxSum = INT_MIN;          int nSum = 0;        for (int i = 0; i < nSize; i++) {            nSum += nums[i];            if (nSum > maxSum)                maxSum = nSum;            if (nSum < 0)                nSum = 0;        }        return maxSum;           }

时间复杂度为O(n)。


0 0
原创粉丝点击