本文參考自《劍指offer》一書,代碼采用Java語言。
題目
假設把某股票的價格按照時間先后順序存儲在數組中,請問買賣交易該股票可能獲得的利潤是多少?例如一只股票在某些時間節點的價格為{9, 11, 8, 5,7, 12, 16, 14}。如果我們能在價格為5的時候買入並在價格為16時賣出,則能收獲最大的利潤11。
思路
遍歷每一個數字,並保存之前最小的數字,兩者差最大即為最大利潤。
值得注意的是,我自己一開始寫的代碼是默認不能虧本(即可以不買入賣出,利潤不能為負數),所以比較簡單;但如果可以虧本,最大利潤指的是最小的虧損,那么要注意最小數字不能是最后一個。在下面的代碼中可以注意比較兩種情況的差別。可以考慮的例子如 { 16, 11, 7, 4, 2, 1 }
測試算例
1.功能測試(數組遞增/遞減/無序)
2.特殊測試(null,空數組)
3.邊界值測試(數組僅兩個數字)
Java代碼
//題目:假設把某股票的價格按照時間先后順序存儲在數組中,請問買賣交易該股 //票可能獲得的利潤是多少?例如一只股票在某些時間節點的價格為{9, 11, 8, 5, //7, 12, 16, 14}。如果我們能在價格為5的時候買入並在價格為16時賣出,則能 //收獲最大的利潤11。 public class MaximalProfit { public static int MaxDiff(int[] arr) { if(arr==null || arr.length<2) return -1; //error int min=arr[0]; //最大利潤可以是負數,只要虧損最小就行 int maxDiff=arr[1]-min; for(int i=1;i<arr.length;i++) { if(arr[i-1]<min) //保存“之前”最小數字 min=arr[i-1]; if(arr[i]-min>maxDiff) maxDiff=arr[i]-min; } //默認不能虧本,代碼簡單,上面復雜的代碼注意細節 // int maxDiff=0; // for(int i=1;i<arr.length;i++) { // if(arr[i]<min) // min=arr[i]; // else if(arr[i]-min>maxDiff) // maxDiff=arr[i]-min; // } return maxDiff; } //簡單快速測試下 public static void main(String[] args) { int[] arr1=null; System.out.println(MaxDiff(arr1)==-1); int[] arr2={ }; System.out.println(MaxDiff(arr2)==-1); int[] arr3={ 16, 16, 16, 16, 16 }; System.out.println(MaxDiff(arr3)==0); int[] arr4={ 1, 2, 4, 7, 11, 16 }; System.out.println(MaxDiff(arr4)==15); int[] arr5={ 16, 11, 7, 4, 2, 1 }; System.out.println(MaxDiff(arr5)==-1); int[] arr6={ 9, 11, 5, 7, 16, 1, 4, 2 }; System.out.println(MaxDiff(arr6)==11); int[] arr7={ 2,4}; System.out.println(MaxDiff(arr7)==2); int[] arr8={ 4,2}; System.out.println(MaxDiff(arr8)==-2); } }

true true true true true true true true
收獲
1.蠻力法時間復雜度為O(n^2),肯定不對。我們從頭到尾遍歷,確定規律。可以發現找出之前的最小值即可。