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 );
    	}
    }
    

      

     
  • 相关阅读:
    校内模拟赛 虫洞(by NiroBC)
    校内模拟赛 旅行(by NiroBC)
    P3830 [SHOI2012]随机树
    4358: permu
    【noi.ac】#309. Mas的童年
    P1438 无聊的数列
    2091: [Poi2010]The Minima Game
    LOJ #6074. 「2017 山东一轮集训 Day6」子序列
    LOJ #6068. 「2017 山东一轮集训 Day4」棋盘
    LOJ #6073. 「2017 山东一轮集训 Day5」距离
  • 原文地址:https://www.cnblogs.com/flyfatty/p/6624811.html
Copyright © 2011-2022 走看看