【分治】面试题 16.17. 连续数列

题目:

给定一个整数数组,找出总和最大的连续数列,并返回总和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:

如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

 

解答:

方法一:分治

class Solution {
    public int maxSubArray(int[] nums) {
        return maxSubArrayAux(nums, 0, nums.length-1);
    }
    int maxSubArrayAux(int[] nums, int left, int right){
        if(left == right)
            return nums[left];
        int mid = (left + right) / 2;
        int leftAux = maxSubArrayAux(nums, left, mid);//左部分最大和
        int rightAux = maxSubArrayAux(nums, mid + 1, right);//右部分最大和
        //注意到这里不管左右能否接上,是因为太麻烦?
        //跨两边最大和,从mid、mid+1往左右两边分别扩展
        int midLeft = nums[mid], midLeftMax = midLeft;
        for(int i = mid-1; i >= left; i--){
            midLeft += nums[i];
            if(midLeft > midLeftMax)
                midLeftMax = midLeft;
        }
        int midRight = nums[mid+1], midRightMax = midRight;
        for(int i = mid + 2; i <= right; i++){
            midRight += nums[i];
            if(midRight > midRightMax)
                midRightMax = midRight;
        }
        return Math.max(Math.max(leftAux, rightAux), midLeftMax + midRightMax);
    }
}

方法二:dp

class Solution {
    public int maxSubArray(int[] nums) {
        int n = nums.length;
        if(n == 0){
            return 0;
        }
       
        int max = nums[0];
        for(int i = 1;i<n;i++){
            if(nums[i-1]>0){
                nums[i] +=nums[i-1];
            }

            if(nums[i]>max){
                    max = nums[i];
            }
        }

        return max;
    }
}

 

posted @ 2020-10-27 23:04  3KBLACK  阅读(156)  评论(0)    收藏  举报