1. 程式人生 > >如何求最大子陣列的和

如何求最大子陣列的和

問題描述:一個有n個元素的陣列,這n個元素可以是正數也可以是負數,陣列中連續的一個或多個元素可以組建成一個連續的子陣列,一個數組可以有多個這樣的連續子陣列,求子陣列和的最大值,並找出最大的子陣列,例如,對於陣列{1,-2,4,8,-4,7,-1,-5},其最大和的子陣列是{4,8,-4,7},最大值為15。

方法一:用比較蠻力的方法並重複利用已經計算過的子陣列和

/**
     * 求連續子陣列的最大和
     * @param array
     * @return
     */
    public static int maxArray(int[] array) {
        int length = array.length;
        int max = Integer.MIN_VALUE;
        int i = 0,j = 0;   //定義兩個陣列 下標,i代表子陣列前面元素下標,j代表後面的
        int tim = 0,pwd = 0;  //定義這兩個變數是為了儲存最大和子陣列的第一個元素和最後一個元素的下標位置
        for(i = 0;i < length;i++) {
            int sum = 0;
            for(j = i;j < length;j++) {
                sum += array[j];
                if(sum > max) {
                    tim = i;
                    pwd = j;
                    max = sum;
                }
            }
        }
        System.out.println("最大子陣列: ");
        while(tim <= pwd) {       
            System.out.print(array[tim]+" ");
            tim++;
        }
        System.out.println();
        return max;
    }

方法二:利用動態規劃方法實現
思路:
首先可以根據陣列的最後一個元素array[n-1]與最大子陣列的關係分為以下三種情況:

  1. 最大和子陣列包含array[n-1],即以array[n-1]結尾;
  2. array[n-1]單獨構成最大子陣列;
  3. 最大子陣列不包含array[n-1],那麼求array[0,……,n-1]的最大子陣列可以轉換為求array[0,……,n-2]的最大子陣列(又回到了第一步,只不過此時原陣列變成了array[0,……,n-2])。

通過上述分析:我們可以假設已經計算出(array[0],……,array[i-1])的最大和子陣列的和為All[i-1],同時也計算出(array[0],……,array[i-1])包含array[i-1]的最大的一段子陣列和為End[i-1],則可以得出如下關係:All[i-1] = max{array[i-1],End[i-1],All[i-2]};為了節省空間,我們定義兩個變數maxEnd、maxAll來儲存End[i-1]與All[i-1]的值,並且反覆利用。

/**
     * 求最大值
     * @param m
     * @param n
     * @return
     */
    public static int max(int m,int n) {
        return m > n ? m : n;
    }

    /**
     * 動態規劃求最長公共子序列
     * @param array
     * @return
     */
    public static int new_maxArray(int[] array) {
        int length = array.length;
        int maxAll = array[0];
        int maxEnd = array[0];
        int start = 0;   //記錄最大和子陣列的起始下標
        int end = 0;    //記錄最大和子陣列的結束下標
        for(int i = 0;i < length;i++) {
            maxEnd = max(maxEnd+array[i],array[i]);
            if(maxEnd == array[i]) {  //如果maxEnd == array[i],那就意味著最大和子陣列的起始位置換了
                start = i;
            }
            maxAll = max(maxEnd,maxAll);
            if(maxAll == maxEnd) {   //★後面有圖解析
                end = i;
            }
        }
        System.out.println("最大和子陣列");
        while(start <= end) {
            System.out.print(array[start]+" ");
            start++;
        }
        System.out.println();
        return maxAll;
    }

★:
在這裡插入圖片描述