數組中元素差的最大值

這道題是2016美團面試題:ios

1.給定一個數組arr,數組長度爲len,求知足 0 <= a <= b < len的 arr[b] - arr[a]最大值。面試

你的想法:讓每個數字減去它右邊的數字,並經過比較獲得數對的最大值,時間複雜度(O^2),這應該是面試官不想要的。數組

解法一:分治法(遞歸實現)ide

假設把數組分紅兩個子數組,用左數組最大的減去右數組最小的,最大值有三種狀況:spa

  (1)被減數和減數都在第一個子數組中,即第一個子數組中的數對之差的最大值;.net

  (2)被減數和減數都在第二個子數組中,即第二個子數組中數對之差的最大值;code

  (3)被減數在第一個子數組中,是第一個子數組的最大值;減數在第二個子數組中,是第二個子數組的最小值。blog

1)、2)、3)中,這三個差值的最大者就是整個數組中數對之差的最大值。遞歸

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 // 解法1: 分治法(遞歸實現)
 5 int Max_Find(int *s,int *e,int *max,int *min)
 6 {
 7     if(s >= e)
 8     {
 9         *max = *min = *s;
10         return -1;
11     }
12     int *mid = s+(e-s)/2;
13 
14     int maxleft,minleft;
15     int left = Max_Find(s,mid,&maxleft,&minleft);
16 
17     int maxright,minright;
18     int right = Max_Find(mid+1,e,&maxright,&minright);
19 
20     int sum = maxleft - minright;
21 
22     *max = (maxleft > maxright) ? maxleft:maxright;
23     *min = (minleft < minright) ? minleft:minright;
24 
25     int m = (left > right) ? left:right;
26 
27     m = (m > sum)?m:sum;
28 
29     return m;
30 }
31 int MaxDiff(int array[], unsigned int len)
32 {
33     if(NULL == array || len < 2){
34         return -1;
35     }
36     int max, min;
37     int MaxDiff_Num = Max_Find(array, array+len-1, &max, &min);
38     printf("maxDiff_Num: %d\n\n", MaxDiff_Num);
39 }
40 
41 int main()
42 {
43     int a[2] = {10,5};
44     MaxDiff(a,2);
45 }
View Code

 

解法二:轉化爲求數字數組最大和問題。get

參考:這裏

使用一個輔助數組arr2,則arr2[i] = arr[i] - arr[i+1]

即:arr2中從i加到j,arr2[i] + arr2[i+1]+.....+arr2[j]

則:(arr[i]-arr[i+1])+(arr[i+1]-arr[i+2])+....(arr[j]-arr[j+1])

轉化爲arr[i]-arr[j+1]

 

 1 #include <iostream>
 2 #include <stack>
 3 #include <algorithm>
 4 #include <stdio.h>
 5 #include <string.h>
 6 #include <stdlib.h>
 7 using namespace std;
 8 int max_find(int arr[],int len)
 9 {
10     if(arr == NULL || len < 2)
11     {
12         return -1;
13     }
14     int *arr2 = new int[len - 1];
15     int i = 0;
16     for(i = 0;i < len-1;++i)
17     {
18         arr2[i] = arr[i] - arr[i+1];
19     }
20     int curS = 0;
21     int max = -1;
22     for(i = 0;i < len-1;++i)
23     {
24         if(curS <= 0)
25         {
26             curS = arr2[i];
27         }else
28         {
29             curS +=arr2[i];
30         }
31         if(curS > max)
32         {
33             max = curS;
34         }
35     }
36     if(arr2)
37     {
38         delete [] arr2;
39         arr2 = NULL;
40     }
41     printf("%d",max);
42 }
43 int main()
44 {
45     int a[2] = {10,5};
46     max_find(a,2);
47 }
View Code

 

解法三:動態規劃法

依次遍歷數組用arr[i-1]以前的最大 值減去右邊的元素

 

 1 #include <iostream>
 2 #include <stack>
 3 #include <algorithm>
 4 #include <stdio.h>
 5 #include <string.h>
 6 #include <stdlib.h>
 7 using namespace std;
 8 int max_find(int arr[],int len)
 9 {
10     if(arr == NULL || len < 2)
11     {
12         return -1;
13     }
14     int max = arr[0];
15     int sum = max - arr[1];//初始化數對差
16     int i = 0;
17     for(i = 2;i < len;++i)
18     {
19         if(arr[i-1] > max)
20         {
21             max = arr[i-1]; //左側最大值
22         }
23         int cur = max - arr[i];//用最大的值減右側的最小值
24         if(cur > sum) //判斷是不是最大數對之差
25         {
26             sum = cur;
27         }
28     }
29     printf("%d",sum);
30 }
31 int main()
32 {
33     int a[2] = {10,5};
34     max_find(a,2);
35 }
View Code

 

 

以上三種都是O(n),那麼:

第一種:遞歸,有遞歸棧

第二種:要n-1輔助數組

第三種:推薦

相關文章
相關標籤/搜索