这道题是2016美团面试题:
1.给定一个数组arr,数组长度为len,求满足 0 <= a <= b < len的 arr[b] - arr[a]最大值。
你的想法:让每一个数字减去它右边的数字,并通过比较得到数对的最大值,时间复杂度(O^2),这应该是面试官不想要的。
解法一:分治法(递归实现)
假设把数组分成两个子数组,用左数组最大的减去右数组最小的,最大值有三种情况:
(1)被减数和减数都在第一个子数组中,即第一个子数组中的数对之差的最大值;
(2)被减数和减数都在第二个子数组中,即第二个子数组中数对之差的最大值;
(3)被减数在第一个子数组中,是第一个子数组的最大值;减数在第二个子数组中,是第二个子数组的最小值。
(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 }