分而治之_最大子数组_1

1. 【问题描述】    最大子数组

2. 【思路】    参考算法导论

采用分而治之的策略。假设数组nums共有N个元素,下标范围 0—N-1,令过程maxBE(nums,beg,end)可以返回nums的下标范围 beg—end的子数组的最大子数组和,即nums[beg,...,end]的最大子数组和,下面对maxBE过程进行分析:

(1). beg==end  则直接返回nums[beg];

(2). beg!=end   则令mid=beg+(end-beg)/2,将数组nums[beg,...,end]拆分为两个子数组nums_left[beg,...,mid]和nums_right[mid+1,...,end],数组nums[beg,...,end]的最大子数组来自以下三种情况中的一种:

2.1 完全来自  nums_left[beg,...,mid];

2.2 完全来自 nums_right[mid+1,...,end];

2.3 由nums_left的尾部一部分和nums_right的头部一部分组成;

2.1和2.2所示的情形是原问题的规模更小的子问题,可以递归调用过程maxBE求解。下面说一下2.3所示情形的解决方法。在这种情况下,最大子数组一定包含原数组nums的元素nums[mid]和nums[mid+1],从下标mid处往前累加数组元素,找到此过程中的累加和的最大值,设为sum_left,从数组下标mid+1往后累加数组元素,找到此过程中累加和的最大值,设为sum_right,则2.3所示情形的最大子数组和是sum_left+sum_right。最终的返回值是2.1、2.2和2.3三种情况中的最大值.

下面以一个小例子分析一下。假设包含三个元素的数组[-2,2,3],下面按行列出分拆过程:

[-2,2,3]    [-2,2]    [3]     

[-2,2]    [-2]    [2]

3.【代码】

class Solution {
public:    
    /**
     * @param nums: A list of integers
     * @return: A integer indicate the sum of max subarray
     */
    int maxBE(vector<int> &nums,int beg,int end) {
        if(beg==end) {
            return nums[beg];
        }
        int mid=beg+(end-beg)/2;
        int i=mid-1,left=nums[mid],ls=left;
        while(i>=beg) {
            ls+=nums[i];
            left=left>=ls?left:ls;
            i--;
        }
        int j=mid+2,right=nums[mid+1],rs=right;
        while(j<=end) {
            rs+=nums[j];
            right=right>=rs?right:rs;
            j++;
        }
        int mid_sum=left+right,left_sum=maxBE(nums,beg,mid),right_sum=maxBE(nums,mid+1,end);
        int sum=left_sum>=right_sum?left_sum:right_sum;
        return sum>=mid_sum?sum:mid_sum;
    }
    int maxSubArray(vector<int> nums) {
        // write your code here
        if(nums.empty()) {
            return 0;
        }
        return maxBE(nums,0,nums.size()-1);
    }
};


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值