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

      

     
  • 相关阅读:
    组合数据类型练习
    实验四、递归下降语法分析实验
    词法分析实验报告
    Python基础综合练习
    大数据概述
    一个词法分析程序
    linux基本命令
    有限自动机的构造与识别
    我对编译原理的小小了解
    Scrum 冲刺博客 2
  • 原文地址:https://www.cnblogs.com/flyfatty/p/6624811.html
Copyright © 2020-2023  润新知