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

    click to show more practice.

    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.

    Ref:http://www.cnblogs.com/feiling/p/3251635.html
    [解题思路]
    如果当前的和小于0,则在后面的数加上现在的和只会比原来的数要小,故舍弃
    O(n)就是一维DP.
    假设A(0, i)区间存在k,使得[k, i]区间是以i结尾区间的最大值, 定义为Max[i], 在这里,当求取Max[i+1]时,
    Max[i+1] = Max[i] + A[i+1],  if (Max[i] + A[i+1] >0)
                    = 0, if(Max[i]+A[i+1] <0),如果和小于零,A[i+1]必为负数,没必要保留,舍弃掉
    然后从左往右扫描,求取Max数字的最大值即为所求。
     
     1 public int maxSubArray(int[] A) {
     2        
     3         int result = Integer.MIN_VALUE;
     4         int curSum = 0;
     5         for(int i = 0; i < A.length; i++){
     6             curSum += A[i];
     7             if(curSum > result){
     8                 result = curSum;
     9             }
    10             if(curSum < 0){
    11                 curSum = 0;
    12             }
    13         }
    14         
    15         return result;
    16     }

    (2) Divide and Conquer

    二分法:将数组分成左右两部分,递归求两部分最大连续子数组,由于最大连续子数组可能横跨左右,故需对这种情况进行处理

    假设数组A[left, right]存在最大值区间[i, j](i>=left & j<=right),以mid = (left + right)/2 分界,无非以下三种情况:

    subarray A[i,..j] is
    (1) Entirely in A[low,mid-1]
    (2) Entirely in A[mid+1,high]
    (3) Across mid
    对于(1) and (2),直接递归求解即可,对于(3),则需要以min为中心,向左及向右扫描求最大值,意味着在A[left, Mid]区间中找出A[i..mid], 而在A[mid+1, right]中找出A[mid+1..j],两者加和即为(3)的解。

    比较三种情况下得到的子数组和,取其中最大值

     1 public int maxSubArray(int[] A) {
     2         // Start typing your Java solution below
     3         // DO NOT write main() function
     4         int max = Integer.MIN_VALUE;
     5         return maxArray(A, 0, A.length - 1, max);
     6     }
     7     
     8     int maxArray(int[] A, int left, int right, int max){
     9         if(left > right){
    10             return Integer.MIN_VALUE;
    11         }
    12         
    13         int mid = (left + right) / 2;
    14         int leftMax = maxArray(A, left, mid - 1, max);
    15         int rightMax = maxArray(A, mid + 1, right, max);
    16         
    17         max = Math.max(max, leftMax);
    18         max = Math.max(max, rightMax);
    19         
    20         int sum = 0, mlmax = 0;
    21         for(int i = mid - 1; i >= left; i--){
    22             sum += A[i];
    23             if(sum > mlmax){
    24                 mlmax = sum;
    25             }
    26         }
    27         sum = 0; int mrmax = 0;
    28         for(int i = mid + 1; i <= right; i++){
    29             sum += A[i];
    30             if(sum > mrmax){
    31                 mrmax = sum;
    32             }
    33         }
    34         max = Math.max(max, A[mid] + mlmax + mrmax);
    35         return max;
    36     }
  • 相关阅读:
    hadoop 之 kafka 安装与 flume -> kafka 整合
    软考倒计时28天:项目一般管理
    HACMP5.4常用命令
    db2还原离线备份文件报错SQL2071N 提示“访问共享库出现错误”解决
    远程桌面不能拷贝文件的问题
    ubuntu设置开机启动命令行模式
    Rainmeter如何打开控制面板的小程序
    /var/adm/wtmp文件太大该怎么办?
    SQL1221N The Application Support Layer heap cannot be allocated. SQLSTATE=57011
    DB21019E An error occurred while accessing the directory "/root".
  • 原文地址:https://www.cnblogs.com/RazerLu/p/3538567.html
Copyright © 2011-2022 走看看