• LeetCode | Maximum Subarray


    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.

    最优解法:

    //O(N)的算法,思想有点类似于双pointer
    //sum为数组前i项和,如果sum为正,那么就留着,如果为负,那么就舍弃,从第i+1项再尝试取subarray累计和
    //如此只需要从前向后一次遍历即可
    public class Solution {
    	 public static int maxSubArray(int[] A) {
    	        
    	        int maxSum = Integer.MIN_VALUE;
    	        int sum = 0;
    	        
    	        for(int i=0; i<A.length; i++){
    	            sum += A[i];    
    	            if(sum > maxSum)
    	                maxSum = sum;
    	            if(sum < 0)         //当前subarray的前i项和为负,舍弃前i项,重新累计求和
    	                sum = 0;
    	        }
    	        
    	        return maxSum;
    	    }
    }

    分治与递归:

    //Divide and Conquer: 算法复杂度为O(NlogN)
    //最大和的subarray有三种可能:即subarray完全位于A的左半部、subarray完全位于A的右半部,或subarray跨越A的中分线
    //第三种情况时,subarray必然包含A左的最后一个元素及A右的第一个元素
    //将三种情况分别求解,取大者返回
    public class Solution {
        
        private int maxSumDAC(int[] array, int left, int right){
            if(left == right) return array[left];
            
            int center = (left+right)/2;
            int maxLeftSum = maxSumDAC(array, left, center);        //分治与递归
            int maxRightSum = maxSumDAC(array, center+1, right);  
            
            int maxLeftBorderSum = Integer.MIN_VALUE;
            int leftBorderSum = 0;
            for(int i=center; i>=left; i--){
                leftBorderSum += array[i];
                if(leftBorderSum > maxLeftBorderSum) maxLeftBorderSum=leftBorderSum;
            }
            
            int maxRightBorderSum = Integer.MIN_VALUE;
            int rightBorderSum = 0;
            for(int i=center+1; i<=right; i++){
                rightBorderSum += array[i];
                if(rightBorderSum > maxRightBorderSum) maxRightBorderSum=rightBorderSum;
            }
            
            if(maxLeftSum>=maxRightSum)                              //三者取大返回
            return Math.max(maxLeftSum, maxLeftBorderSum+maxRightBorderSum);
            else
            return Math.max(maxRightSum, maxLeftBorderSum+maxRightBorderSum);
        }
        
        public int maxSubArray(int[] A) {
            return maxSumDAC(A, 0, A.length-1);
        }
        
    }


    两种遍历方法:

    public class Solution {
        public int maxSubArray(int[] A) {
            
            int maxSum = Integer.MIN_VALUE;
            
            for(int i=0; i<A.length; i++)      //通过三重循环,穷举所有可能子数组的和
            for(int j=i; j<A.length; j++){
                int sum = 0;
                for(int k=i; k<=j; k++){       //取i-j内的subarray求和
                    sum += A[k];
                }
                if(sum > maxSum) maxSum = sum;
            }                                  //算法为O(N3),提示超时
            
            return maxSum;
        }
    }
    
    
    public class Solution {
        public int maxSubArray(int[] A) {
            
            int maxSum = Integer.MIN_VALUE;
            
            for(int i=0; i<A.length; i++){           //算法为O(N2),提示超时
                int sum = 0;
                for(int j=i; j<A.length; j++){       //在内循环内,计算i-j的子数组的和
                    sum += A[j];
                    if(sum > maxSum) maxSum = sum;
                }
                //if(sum > maxSum) maxSum = sum;     //注意:判断语句不能放在此处
            }                                        //因为在内循环内,每一个j就求了一个子数组和
                                                     //如果if放到外面,就相当于整个数组A求和,再与maxSum比了
            return maxSum;
        }
    }



  • 相关阅读:
    JAVA SSH 框架介绍
    Web开发者不可不知的15条编码原则
    全选,反选,全不选
    Python函数
    Python变量解析
    Python输入/输出语句
    Python程序基本架构
    Python开发环境安装
    java事件
    测试博客
  • 原文地址:https://www.cnblogs.com/dosmile/p/6444454.html
Copyright © 2020-2023  润新知