剑指Offer31连续子数组的最大和

题目:


输入一个整形数组,数据里有正数也有负数,数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)

例如输入数组{1,-2,3,10,-4,7,2,-5};


分析:

最简单的方法就是枚举每一种情况,当然这是不符合题意的,因为题目中要求时间复杂度是O(n),而如果枚举的话是O(n2)。

有两种理解方法来对应本题。

方法一:

首先我们可以遍历这个数组,一个个来。首先我们把sum=0;当进行到一个数时就加上此时sum = 1,然后第二个此时sum = -1.因为这个数是一个负数,就算后面的数再大,也不可能从它的基础上往后加了,所以我们抛弃这个数,接下来从3开始,sum=3;再往后sum=13,再往后sum=9,此时9小于13,我们保留之前的13它有可能是最大的(如果后面还有更大的数那么它就没有可能做老大了),再往后sum=16,它比13大,所以13就不要了,更新成了16,再往后sum=18,直到最后一个sum=13,因为没有18大,并且是最后一个数了,所以最后的答案是18.

依据咱们上面的过程就可以写出代码了:

int FindMaxSumOfSubArray(int *date,int length)
{
    if(date == NULL || length < 0)
    {
        cout<<"空指针异常"<<endl;
        return 0;
    }
    int sum =0;
    int maxSum = 0;
    for(int i=0;i<length;i++)
    {
        if(sum <= 0)
            sum = date[i];
        else
            sum += date[i];

        if(sum > maxSum )
            maxSum = sum;
    }
    return maxSum;
}

方法二:

动态规划,这是最简单的一个动态规划的题目。

如果用函数f(i)表示第i个数字结尾的子数组的最大和,那么我们需要求出max f(i),就是我们要的结果,

f(i)={

data[i]        i=0或者f(i-1)<=0

f(i-1)+data[i]   i != 0或者f(i-1)>0

}


公式的意义:当以第i-1个数字结尾的子数组中所有数字的和小于0时,如果把这个负数与第i个数累加,得到的结果比第i个数字本身还要小,所以这种情况下以第i个数字结尾的子数组就是第i个 数字本身,如果以第i-1个数字结尾的子数组中所有数字的和大于0,与第i个数字累加就得到以第i个数字结尾的子数组中所有数字的和。

虽然思路不一样,但是所形成的代码是一样的


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值