算法分析与设计课程作业第二周#1

算法分析与设计课程作业第二周#1

上一周学了分而治之的算法策略,这周就先找了一题贴了此标签的题试试手。

题目:Maximum Subarray

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记录从某个值开始的连续序列的和,其一开始从整个序列的第一个值开始,一旦sum小于0,就表示前面已经计算的序列的和若再加到后面的序列和上,序列和只会更小,所以就舍弃前面的序列和,从使sum为0的序列值的下一个值开始计算sum,另一个maxsum记录到此为止的连续子数组的最大和(也是其中某个连续序列的和),通过比较maxsum和sum,一旦得到一个更大的和值,就设置该变量。总之,sum在计算中就是其中某个连续子序列的和,maxsum就是计算中最大的sum值,这样maxsum即是该数组中的一个连续子数组的最大和。

代码块

第一次错误(没考虑到数组一开始可以为负值):

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum = 0, maxsum = 0;
        for(int i = 0; i < nums.size(); i++){
            sum += nums[i];
            maxsum = maxsum > sum? maxsum : sum;
            if(sum < 0) sum = 0;
        }
        return maxsum;
    }
};

maxsum一开始不应设置为0,应设置为一个无论如何都小于等于后面计算的sum的数,以免后面计算的maxsum是一个不存在的初始值,所以可以设置为序列的第一个元素的值。
正确版本:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum = 0, maxsum = nums[0];
        for(int i = 0; i < nums.size(); i++){
            sum += nums[i];
            maxsum = maxsum > sum? maxsum : sum;
            if(sum < 0) sum = 0;
        }
        return maxsum;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值