zoukankan      html  css  js  c++  java
  • [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.

    More practice:

    If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

    https://oj.leetcode.com/problems/maximum-subarray/

    思路1:Kadane算法,复杂度O(n)。

    思路2:分治。对于每次递归,将数组分半,最大和可能存在

    1. 完全在左面部分(递归求解)
    2. 完全在右面部分(递归求解)
    3. 横跨左右两个部分(从中间(必须包含中间元素,否则左右无法连接)向两边加,记录最大值)

    注意点:注意负数的处理,此题最大值为负数时依然返回最大的负数,也有题目负数时要求返回0。注意两种情况下最大值的初始化等细节的区别。

    思路1代码:

    public class Solution {
    	public int maxSubArray(int[] A) {
    		int n = A.length;
    		int i;
    		int maxSum = A[0];
    		int thisSum = 0;
    		for (i = 0; i < n; i++) {
    			thisSum += A[i];
    			if (thisSum > maxSum)
    				maxSum = thisSum;
    			if (thisSum < 0)
    				thisSum = 0;
    		}
    		return maxSum;
    	}
    
    	public static void main(String[] args) {
    		System.out.println(new Solution().maxSubArray(new int[] { -2, 1, -3, 4,
    				-1, 2, 1, -5, 4 }));
    	}
    }

    思路2代码:

    public class Solution {
        public int maxSubArray(int[] A) {
            return maxSub(A, 0, A.length - 1);
        }
    
        private int maxSub(int[] a, int left, int right) {
            if (left == right)
                return a[left];
            int mid = (left + right) / 2;
            int maxLeft = maxSub(a, left, mid);
            int maxRight = maxSub(a, mid + 1, right);
    
            int leftHalf = 0, leftHalfMax = Integer.MIN_VALUE;
            int rightHalf = 0, rightHalfMax = Integer.MIN_VALUE;
    
            for (int i = mid; i >= left; i--) {
                leftHalf += a[i];
                if (leftHalf > leftHalfMax)
                    leftHalfMax = leftHalf;
            }
    
            for (int i = mid + 1; i <= right; i++) {
                rightHalf += a[i];
                if (rightHalf > rightHalfMax)
                    rightHalfMax = rightHalf;
            }
    
            return Math.max(Math.max(maxLeft, maxRight), (leftHalfMax + rightHalfMax));
        }
    
        public static void main(String[] args) {
            System.out.println(new Solution().maxSubArray(new int[] { -2, -1, -3, -2, -5 }));
        }
    }

    第三遍记录:
      注意递归终止条件: 如果right边界是incluside的情况, 跳出的情况要是(left>=right),有可能right比left还小。
    public class Solution {
        public int maxSubArray(int[] A) {
            int n = A.length;
            return maxSub(A,0,A.length-1);
        }
        
        private int maxSub(int[] A, int left, int right){
            if(left>=right){
                return A[left];
            }
            int mid = left+(right-left)/2;
            int leftMax = maxSub(A,left,mid-1);
            int rightMax=maxSub(A,mid+1,right);
            
            
            int midLeftSum=0;
            int thisSum=0;
            for(int i=mid-1;i>=left;i--){
                thisSum+=A[i];
                if(thisSum>midLeftSum){
                    midLeftSum=thisSum;
                }
            }
            int midRightSum=0;
            thisSum=0;
            for(int i=mid+1;i<=right;i++){
                thisSum+=A[i];
                if(thisSum>midRightSum){
                    midRightSum=thisSum;
                }
            }
            
            return Math.max(midLeftSum+A[mid]+midRightSum,Math.max(leftMax,rightMax));
            
        }
        
    }

    补充记录:DP解法,时空复杂度都是O(N), 可以推广到求 两个子序列的最大和(类似股票第三题),用前后两个dp解决。

    public class Solution {
        public int maxSubArray(int[] a) {
            int n = a.length;
            int[] dp = new int[n];
            int res = a[0];
            dp[0] = a[0];
            for (int i = 1; i < n; i++) {
                dp[i] = Math.max(dp[i - 1] + a[i], a[i]);
                res = Math.max(res, dp[i]);
            }
            return res;
        }
        
    }
    参考:

    Data Structures and Algorithm Analysis in C

    http://blog.csdn.net/xshengh/article/details/12708291

  • 相关阅读:
    Apache ActiveMQ 远程代码执行漏洞 (CVE-2016-3088)案例分析
    linux 软中断过高性能优化案例
    jvm默认的并行垃圾回收器和G1垃圾回收器性能对比
    JVM性能参数优化
    一次压测中tomcat生成session释放不及时导致的频繁fullgc性能优化案例
    sed命令实现文件内容替换总结案例
    You have new mail in /var/spool/mail/root消除提示的方法
    zookeeper常用命令
    mongodb输错命令后不能删除问题
    centos环境gcc版本升级
  • 原文地址:https://www.cnblogs.com/jdflyfly/p/3810766.html
Copyright © 2011-2022 走看看