分而治之_最大子数组_1

来源:互联网 发布:fireworks mac 编辑:程序博客网 时间:2024/05/16 06:35

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 0
原创粉丝点击