1. 程式人生 > 其它 >劍指offer程式碼解析——面試題31連續子陣列的最大和

劍指offer程式碼解析——面試題31連續子陣列的最大和

題目:輸入一個整型陣列,數組裡有正數也有負數。陣列中一個或連續的多個整陣列成一個子陣列。求所有子陣列和的最大值。要求時間複雜度為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