程序员面试题精选100题<5>-数对之差的最大值
题目:在数组中,数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。例如在数组{2, 4, 1, 16, 7, 5, 11, 9}中,数对之差的最大值是11,是16减去5的结果。
分析:
1.通过减小问题的规模来求解
可将数组分成左右两个部分分别求解,这样可就出现三种情况:
a. 差的最大值在左边的数组里
b. 差的最大值在右边的数组里
c. 用左边数组的最大值减去右边数组的最小值得到数对之差的最大值
很显然这是分而治之的思想,即:分治法。
分治法利用的是递归。 时间复杂度为O(nlgn),具体计算可参考《算法导论》第一章 递归树
2. 从右向左扫描数组,记录下遍历过程的最小值和差的最大值。
a. 当array[i]< min 时,min = array[i]
b. 当array[i]> min 时,计算diff = array[i] – min , maxdiff = MAX(maxdiff,diff)
遍历完数组时,即可得到书对之差的最大值
由以上分析,时间复杂度为O(n),空间复杂度为O(1)
代码:
1. 分治法:
1: #define MAX(a,b) ((a)>(b)?(a):(b))2: #define MIN(a,b) ((a)>(b)?(b):(a))3: #define MAXINT (~(1<<31))4: #define MININT (1<<31)5:6: int maxDiff(int* array,int l,int r,int& max, int& min)7: {8: assert(array && l<r) ;// array can't be null and size must >=2
9: int mid = 0 ;
10: int lmax , rmax ;
11: int lmin , rmin ;
12: int diff, ldiff, rdiff, cdiff ;
13: for(int i=l;i<=r;++i){14: cout << array[i] << " " ;
15: }16: cout << endl ;17: if (1==r-l){// the array size is 218: diff = array[l] - array[r] ;19: max = MAX(array[l],array[r]) ;20: min = MIN(array[l],array[r]) ;21: return diff ;
22: }else if (2==r-l){ // the array size is 323: int diff1 = array[l] - array[l+1] ;
24: int diff2 = array[l] - array[r] ;
25: int diff3 = array[l+1] - array[r] ;
26: diff = MAX(MAX(diff1,diff2),diff3) ;27: max = MAX(MAX(array[l],array[l+1]),array[r]) ;28: min = MIN(MIN(array[l],array[l+1]),array[r]) ;29: return diff ;
30: }else{ // the array size > 331: mid = (l+r) / 2 ;32: ldiff = maxDiff(array,l,mid,lmax,lmin) ;33: rdiff = maxDiff(array,mid+1,r,rmax,rmin) ;34: cdiff = MAX(lmax,lmin) - MIN(rmax,rmin) ;35: //get the max diff
36: diff = MAX(MAX(ldiff,rdiff),cdiff) ;37: // get the max value in this team
38: max = MAX(lmax,rmax) ;39: // get the min value int this team
40: min = MIN(lmin,rmin) ;41: return diff ;
42: }43: }44: int getMaxDiff(int* array,int len)45: {46: int max = MININT ;
47: int min = MAXINT ;
48: return maxDiff(array,0,len-1,max,min) ;
49: }
2 从后向前遍历
1: int getMaxDiff(int array[],int len)2: {3: assert(array && len>1) ;4: int min = MIN(array[len-1],array[len-2]);
5: int maxdiff = array[len-2] - array[len-1] ;
6: for(int i=len-3;i>=0;--i){7: if (min > array[i]){
8: min = array[i] ;9: }else {
10: maxdiff = MAX(maxdiff,array[i]-min) ;11: }12: }13: return maxdiff ;
14: }