微软100题第3题:求子数组的最大和


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

例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。


分析:该题也是Leetcode上面的题目,第53题。题方法有多种, 本次用两种时间复杂度最低的方式实现。

方法1:动态规划O[N],分析题目后,最大的连续子序列和从以当前元素pData[i]结尾的序列和中找,当前元素结尾的序列和为f(i).

f(i)= pData[i], i=0 or f(i-1)<=0; or f(i) = f(i-1)+pData[i], i!=0 and f(i-1)>0

取 MAX(f(i)), i>=0 and i<n;

int maxSubArray( vector<int> & nums )
{
    int cursum=0, maxsum=nums[0];
    for( vector<int>::size_type i=0; i!= nums.size(); i++ )
    {
        cursum += nums[i];
        if( cursum > maxsum )
        {
            maxsum = cursum;
        }
        if(cursum <0)
            cursum = 0;
    }

    return maxsum ;
}

方法2:使用“分而治之”策略,O[NlogN]。最大连续子序列和最可能出现在序列的3个地方, 只需取三个数据中最大的那个即可。

a. 数组的左半边;

b. 数组的右半边;

c. 跨越左右,中间的某一段区间。

前两种情况采用递归即可处理。

static int MaxSubSum( vector<int> & nums  , int left, int right)
{
    int mid=(left +right)/2, maxleft=0, maxright=0;
    int leftsum=0, rightsum=0;
    int maximum =0;

    if(left == right)
    {
        //if(nums[left] >0)
            return nums[left] ;
    }
    maxleft = MaxSubSum(nums, left, mid);
    maxright = MaxSubSum(nums, mid+1, right);

    if(maxleft>maxright)
        maximum = maxleft;
    else
        maximum = maxright;

    maxleft = nums[mid];
    maxright = nums[mid+1];

    for(int i=mid; i>=left; i--)
    {
        leftsum += nums[i];
        if(leftsum > maxleft)
            maxleft = leftsum;
    }

    for(int i= mid+1; i<=right; i++)
    {
        rightsum += nums[i];
        if(rightsum > maxright)
            maxright = rightsum;
    }

    return maximum = ((maxleft + maxright) > maximum)?(maxleft + maxright) : maximum;
}

int maxSubArray( vector<int> & nums )
{
    return MaxSubSum(nums, 0, nums.size()-1);
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值