資料結構演算法題/陣列中兩個數相減(前面減後面)的最大值
陣列中兩個數相減(前面減後面)的最大值。
解法一:O(n^2)
就是一個很普通的方法。求出 陣列中所有下標小的元素減去下標大的元素,找出其中的最大值即可。程式碼如下:
//O(N^2) 找出陣列arr中兩個數相減的最大值
public static int maxValueSub(int[] arr){
int max = 0;
int sub;
for(int i = 0; i < arr.length; i++){
for(int j = i+1; j < arr.length; j++){
sub = arr[i] - arr[j];
if(sub > max)
max = sub;
}
}
return max;
}
解法二:O(n)
使用兩個指標,初始值設為指向第一個數和第二個數,如下圖所示:
p1,p2指向前兩個數,初始的最大值就是max=9-1=8。然後p1保持不變,移動p2指標,每移動一次計算p1指向的值和p2指向的值之差,如果大於max,則更新max,直到p2指向第一個大於p1的值。
這時候再拿p1減去p2後面的值就沒有意義了,因為p1<p2,拿p1減p2後面的值肯定不會比p2減去它後面的值大。因此我們把指標p1指向p2的位置,p2後移一位。如下圖所示,直到p2到達陣列末尾。
這裡面跳過了第二幅圖中p1和p2中間的數相減的情況,當p1指向9,p2指向18,9和18之間的兩個數相減有沒有可能更大呢?可以證明不存在這種情況。假設p1和p2之間存在兩個數n1和n2有n1-n2更大,由於p2是第一個大於p1的數,所以n1<p1,,那麼p1-n2>n1-n2,矛盾,可知這種情況不存在。時間複雜度O(n).
/** * 陣列中兩個數相減(前面減後面)的最大值 * 兩個指標p1和p2 * 時間複雜度O(n) */ public class ArrMaxMinus2 { int GetMaxOfFormerSubLatter(int[] arr) { int p1 = 0; int p2 = 1; int max = arr[p1] - arr[p2]; int n = arr.length-1; while(p2 < n) { while(arr[p2] < arr[p1] && p2 < n) { if(arr[p1] - arr[p2] > max) max = arr[p1] - arr[p2]; ++p2; } //arr[p2] > arr[p1] 後面遇到更大的元素,那麼就把p1置位p2,新的p2後移一位 p1 = p2; ++p2; } return max; } public static void main(String[] args) { ArrMaxMinus2 arrMaxMinus = new ArrMaxMinus2(); int[] arr = {9,1,7,18,3,-5,20,4,0,5}; System.out.println(arrMaxMinus.GetMaxOfFormerSubLatter(arr)); } }