【分治】面试题 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; } }

浙公网安备 33010602011771号