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

      

     
  • 相关阅读:
    深入了解CSS字体度量,行高和vertical-align
    解决ios手机上传竖拍照片旋转90度问题
    HTML5图片上传本地预览
    前端本地文件操作与上传
    前端基础进阶(一):内存空间详细图解
    js小知识-数组去重
    SQL Server物化视图学习笔记
    MindMaster学习笔记
    c#Lock学习笔记
    oauth2.0学习笔记(摘抄简化)
  • 原文地址:https://www.cnblogs.com/flyfatty/p/6624811.html
Copyright © 2011-2022 走看看