leetcode [Maximum Subarray]

来源:互联网 发布:扫鬼软件下载 编辑:程序博客网 时间:2024/06/06 01:43
class Solution{/* *要寻找最大的子序列和,说明存在一个比较,则用maxSum来存最后要返回的结果,用thisSum来存中间过程的序列和 *那么什么时候比较maxSum与thisSum? *只要thisSum比maxSum大,就将maxSum更新为thisSum,同时thisSum继续加后面的数 *只要thisSum加上一个数时小于0了就说明应该重新开始了,但是前面的maxSum要留下来作为比较 */    public int maxSubArray(int[] nums) {        int maxSum = nums[0];//maxSum用来保存序列和最大值        //maxSum就是返回的值,所以要用nums[0]不能用0        int thisSum = 0;//thisSum用来保存中间过程的序列和        for(int i = 0; i < nums.length; i++){        thisSum += nums[i];        if(thisSum >= maxSum) maxSum = thisSum;//细节:这里用thisSum >= maxSum而不用thisSum > maxSum除了因为最大连续子序列和可以有0外,还因为在i=0时thisSum是等于maxSum的        //else if(thisSum < 0) thisSum = 0;          if(thisSum < 0) thisSum = 0;// 改成if 而不是else if 不论前面怎样这一句一定要有        }        return maxSum;    }}

解法二(分治算法):

    public int maxSubArray(int[] nums) {    int res = divide(nums, 0, nums.length - 1);    return res;    }        public int divide(int[] nums, int left, int right){    /*     *采用分治算法,将这个数列分成左右两部分,分别求出左侧和右侧的最大子序列和     *但是还有一种可能就是这个数列的最大子序列和刚好出现在中间部分,所以需要求出     *最后比较左侧,中部,右侧三个最大子序列和的大小,取最大值即为该数列的最大连续子序列和      */        //写分治算法时就只用考虑最开始那个整体怎样分怎样治,然后找到递归出口        int res = 0;    if(left >= right) return nums[left];//递归出口,不要写成if(left == right),if(left >= right)更全面    int mid = (left + right) / 2;        //分        int leftSum = divide(nums, left, mid);//左侧    int rightSum = divide(nums, mid + 1, right);//右侧    int midl = nums[mid], midr = nums[mid + 1];//求中间部分    int thisl = 0, thisr = 0;        //这里只用从中间往左找第一个连续的最大的就行,前面的不用管了    for(int i = mid; i >= left; i--){//i >= left而不是i >= 0,这是分治!!    thisl += nums[i];    if(thisl >= midl) midl = thisl;//只用从中间往左找第一个连续的最大的就行,前面的不用管了,所以不用考虑thisl小于0时重新开始    }    //这里只用从中间往右找第一个连续的最大的就行,后面的不用管了    for(int i = mid +1 ; i <= right; i++){//i <= right而不是i < nums.length,这是分治!!    thisr += nums[i];    if(thisr >= midr) midr = thisr;//只用从中间往右找第一个连续的最大的就行,后面的不用管了,所以不用考虑thisr小于0时重新开始    }    int midSum = midl + midr;//一定要加上,不能比大小求最大值,要不然就和单独一侧的最大连续子序列和没区别了        //治        res = Math.max(midSum, Math.max(leftSum, rightSum));        return res;    }


0 0
原创粉丝点击