HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同窗。今天測試組開完會後,他又發話了:在古老的一維模式識別中,經常須要計算連續子向量的最大和,當向量全爲正數的時候,問題很好解決。可是,若是向量中包含負數,是否應該包含某個負數,並指望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和爲8(從第0個開始,到第3個爲止)。你會不會被他忽悠住?算法
求連續子數組的最大和,首先想的到最笨的方法就是暴力解決,兩個for循環,遍歷數組找到和最大的子數組。示例代碼:數組
/* * 連續子數組的最大和 */ public class Solution_31 { public static void main(String[] args) { System.out.println(FindGreatestSumOfSubArray(new int[]{ -2, -8, -1, -5, -9 })); } public static int FindGreatestSumOfSubArray(int[] array) { if(array==null||array.length<=0) return 0; int maxSumOfSubArray = Integer.MIN_VALUE; for (int i = 0; i < array.length; i++) { int sum = array[i]; if (sum > maxSumOfSubArray) { maxSumOfSubArray = sum; } for (int j = i + 1; j < array.length; j++) { if (sum + array[j] > maxSumOfSubArray) { maxSumOfSubArray = sum + array[j]; } sum = sum + array[j]; } } return maxSumOfSubArray; } }
還有一種方法是,掃描一遍數組,並設置一個變量,保存已經掃描過的sum值,每掃描一個數,若是sum<0,則加上這個數後必定比當前這個數小,因此讓sum等於當前這個數,若是sum>=0,則讓sum=sum+當前這個數。掃描的過程還有比較Max和sum的值,取較大值。示例代碼以下:測試
public class Solution { public int FindGreatestSumOfSubArray(int[] array) { if(array==null||array.length<=0) return 0; int sum = array[0]; int maxSumOfSubArray = sum; for (int i = 1; i < array.length; i++) { if (sum >=0) { sum=sum+array[i]; } else sum=array[i]; if(sum>maxSumOfSubArray) maxSumOfSubArray=sum; } return maxSumOfSubArray; } }
最後,還有一種經典的動態規劃算法(跟第二種方法相似),咱們要找到狀態轉移方程:spa
假設f(j)表示從是s[0]到s[j]最大和,則f(j)=max(s[j],f(j-1)+s[j])。示例代碼以下:code
public static int FindGreatestSumOfSubArray3(int[] array) { if(array==null||array.length<=0) return 0; int maxSumOfSubArray = Integer.MIN_VALUE; int sum=0; for (int i = 0; i < array.length; i++) { sum=Math.max(array[i], array[i]+sum); maxSumOfSubArray=Math.max(maxSumOfSubArray,sum); } return maxSumOfSubArray; }