zoukankan      html  css  js  c++  java
  • 53. Maximum Subarray【DP|分治】

    2017/3/23 17:52:07

    Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

    For example, given the array [-2,1,-3,4,-1,2,1,-5,4],
    the contiguous subarray [4,-1,2,1] has the largest sum = 6.


    版本1 : DP    O(n)   状态转移方程 state(k) = max( state(k) , state(k-1) + state(k) )
    1. public class Solution {
          public int maxSubArray(int[] nums) {
              int sum = nums[0] ;
              for ( int i=1;i<nums.length;i++ ){
              	nums[i] = Math.max( nums[i], nums[i-1]+nums[i] );
              	sum = Math.max( sum , nums[i] );
              }
      		return sum;
          }
      }
      

        

     
    版本2:分治(参考discuss思路如下)  O(nlogn) 
     

    Step1. Select the middle element of the array.
    So the maximum subarray may contain that middle element or not.

    Step 2.1 If the maximum subarray does not contain the middle element, then we can apply the same algorithm to the the subarray to the left of the middle element and the subarray to the right of the middle element.

    Step 2.2 If the maximum subarray does contain the middle element, then the result will be simply the maximum suffix subarray of the left subarray plus the maximum prefix subarray of the right subarray

    Step 3 return the maximum of those three answer.

    Here is a sample code for divide and conquer solution. Please try to understand the algorithm before look at the code
    public class Solution {
        public int maxSubArray(int[] nums) {
            if ( nums.length == 0 ) return 0;
            return getMaxSubArray( nums , 0 , nums.length-1 );
        }
        public int getMaxSubArray( int[] nums , int low , int high ){
    		if ( low == high ) return nums[low];
    		int mid = ( low + high ) / 2;
    		int left_fix = nums[mid] , right_fix = 0;
    		int left_sum = nums[mid] , right_sum = 0;//左边的累计和必选mid,右边不必选mid
    		for ( int i=1 ; i<=mid-low ; i++ ){//左右同时开工;左边可能会多一个元素
    			left_fix = Math.max(left_fix, left_sum = left_sum+nums[mid-i]);
    			right_fix = Math.max(right_fix, right_sum = right_sum+nums[mid+i]);
    		}
    		right_fix = ((high - low ) & 0x1) == 1 ? Math.max(right_fix, right_sum = right_sum+nums[high]) : right_fix;
    		int leftmax = getMaxSubArray(nums , low, mid );
    		int rightmax = getMaxSubArray(nums , mid+1, high);
    		return Math.max( Math.max(leftmax , rightmax ), left_fix + right_fix );
    	}
    }
    

      

     
  • 相关阅读:
    【codeforces 797C】Minimal string
    【codeforces 797E】Array Queries
    【codeforces 796C】Bank Hacking(用一些技巧来代替multiset)
    【POJ 1860】Currency Exchange
    【微软2017年预科生计划在线编程笔试 A】Legendary Items
    【微软2017年预科生计划在线编程笔试 B】Tree Restoration
    【codeforces 797D】Broken BST
    【[Offer收割]编程练习赛11 C】岛屿3
    【[Offer收割]编程练习赛11 B】物品价值
    【codeforces 789D】Weird journey
  • 原文地址:https://www.cnblogs.com/flyfatty/p/6624811.html
Copyright © 2011-2022 走看看