LeetCode53. Maximum Subarray(easy)

原题地址:https://leetcode.com/problems/maximum-subarray/description/


题目:
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.


题解:
写这道题比较艰难。比较容易看出的解题思路就是通过判断当前累加的值决定最大子数组范围。比如,当前累加的值sum小于0时,就意味着可以把之前所有累加的值舍弃,并指向下一个元素。但我一直在思考如何同时确定两边的范围而不冲突,这就导致我陷入了一个死胡同,为此还花相当多的时间写了一个计算两边累加之和最小,然后再用总的和减去这个数的程序,但因为用到了嵌套循环,这个程序时间复杂度非常糟糕。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int size = nums.size(), count = 0, maxNum = 0, sum = 0;
        for (int i = 0; i < size; i++) {
            sum += nums[i];
            if (nums[i] < 0) count++;
        }
        if (count == size) {            
            maxNum = nums[0];
            for (int i = 1; i < size; i++)
                if (nums[i] > maxNum) maxNum = nums[i];
            return maxNum;
        }
        else if (count == 0) {              
            return sum;
        }
        map<int, int> sumls, sumrs;
        sumls.insert(make_pair(-1, 0));
        sumrs.insert(make_pair(size, 0));
        vector<int> sums;
        int suml = 0, sumr = 0;
        for (int i = 0, j = size-1; i < size, j >= 0; i++, j--) {
            suml += nums[i];
            if (suml < 0) sumls.insert(make_pair(i, suml));
            sumr += nums[j];
            if (sumr < 0) sumrs.insert(make_pair(j, sumr));
        }
        int minNum = 0;
        for (map<int, int>::iterator i = sumls.begin(); i != sumls.end(); i++) {
            map<int, int>::iterator j;
            if (sumrs.find(i->first + 1) == sumrs.end())
                j = sumrs.begin();
            else
                j = sumrs.find(i->first + 1);
            for (; j != sumrs.end(); j++) {
                if (i->first < j->first&&i->second + j->second < minNum) minNum = i->second + j->second;
            }
        }
        maxNum = sum - minNum;
        return maxNum;
    }
};

后来看了其他人的代码后发现,之前的思路是没有问题的,但是问题我无法确定另一侧的边界。因为在sum加上一个负数之后但是其值仍然大于0后,程序仍然会继续运行,但是这就不会是最大值,也无法确定之后是否sum会变得更大,因此我认为应该同时确定两个边界。事实上是我把问题想复杂化了,只需要使用一个变量,保存当前最大值,每次把新的sum和它做比较,再确定是否替换。这样就可以确保在所有区域中,能够选取和最大的一个。


新的代码如下:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int maxNumber = INT_MIN, sum = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (sum > 0) {
                sum += nums[i];
            } else {
                sum = nums[i];
            }
            maxNumber = max(sum, maxNumber);
        }
        return maxNumber;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值