劍指offer程式碼解析——面試題31連續子陣列的最大和
阿新 • • 發佈:2022-05-03
題目:輸入一個整型陣列,數組裡有正數也有負數。陣列中一個或連續的多個整陣列成一個子陣列。求所有子陣列和的最大值。要求時間複雜度為O(n)
分析:統計連續子陣列的最大值最直觀的方法就是遍歷陣列n次,每次以a[i]作為子陣列的起點,然後將a[i]後面的數字依次納入陣列中,計算最大值。這種方式的時間複雜度為O(n^2),顯然不符合要求。下面我們根據陣列自身的特點來統計連續子陣列的最大值。
我們嘗試從左向右遍歷陣列,並且進行累加。我們就會發現:如果當陣列累加到a[i]後,累加的結果反而小於a[i]本身,那就說明a[0]+……+a[i-1]是一個負數。那麼這個負數會拖累a[i]後面累加的結果,即:a[0]+……+a[i-1]+a[i]+……+a[n] < a[i]+……+a[n]。既然如此,當我們發現累加進行到a[i]時,如果累加的結果反而小於a[i]本身,就把a[i]前面的所有數全都丟掉,累加從a[i]重新開始。與此同時,用一個全域性變數記錄當前子陣列的最大值。那麼當掃描完一遍陣列後,那個最大值就是我們要的結果。程式碼如下:
/** * 題目:輸入一個整型陣列,數組裡有正數也有負數。陣列中一個或連續的多個整陣列成一個子陣列。求所有子陣列的和的最大值。要求時間複雜度為O(n) * @author 大閒人柴毛毛 * @date 2016年3月16日 */ public class MaxSubArray { /** * 計運算元陣列和的最大值 * @param a 陣列 * @return 返回子陣列和的最大值 */ private static boolean result = true;//用於標識本函式執行過程是否正常 public static int getMaxSubArray(int[] a){ //陣列為空 if(a==null || a.length<=0){ System.out.println("陣列為空!"); result = false; return -1; } int max = 0;//記錄當前子陣列最大值 int sum = 0;//記錄當前子陣列的和 //掃描陣列 for(int i=0;i<a.length;i++){ //計算當前子陣列的和 sum += a[i]; //若a[i]比sum大 if(a[i]>sum){ //丟掉a[i]之前累加結果,把a[i]作為子陣列的起點 sum = a[i]; max = a[i]; } //若a[i]比sum小,則判斷sum是否>max,若sum>max,則更新max if(sum > max) max = sum; } return max; } /** * 測試 */ public static void main(String[] args){ int[] a = {1,-2,3,10,-4,7,2,1,-5}; System.out.println("函式執行結果:"+result); System.out.println("最大值="+getMaxSubArray(a)); } }
執行結果:
函式執行結果:true
最大值=19