• 程序员面试题精选100题(61)数对之差的最大值


    题目:在数组中,数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。例如在数组{2, 4, 1, 16, 7, 5, 11, 9}中,数对之差的最大值是11,是16减去5的结果。

    分治策略:

    通常蛮力法不会是最好的解法,我们想办法减少减法的次数。假设我们把数组分成两个子数组,我们其实没有必要拿左边的子数组中较小的数字去和右边的子数组中较大的数字作减法。我们可以想象,数对之差的最大值只有可能是下面三种情况之一:(

    1)被减数和减数都在第一个子数组中,即第一个子数组中的数对之差的最大值;(2)被减数和减数都在第二个子数组中,即第二个子数组中数对之差的最大值;(3)被减数在第一个子数组中,是第一个子数组的最大值。减数在第二个子数组中,是第二个子数组的最小值。这三个差值的最大者就是整个数组中数对之差的最大值。

    在前面提到的三种情况中,得到第一个子数组的最大值和第二子数组的最小值不是一件难事,但如何得到两个子数组中的数对之差的最大值?这其实是原始问题的子问题,我们可以递归地解决。下面是这种思路的参考代码:

    #include <iostream>
    using namespace std;

    int MaxDiffCore(int* start,int* end,int* max,int* min){//分之策略
    if(end == start){//递归用法的前提
    *max = *min = *start;
    return 0;
    }

    int* middle = start+(end-start)/2;

    int maxLeft,minLeft;
    int leftDiff = MaxDiffCore(start,middle,&maxLeft,&minLeft);

    int maxRight,minRight;
    int rightDiff = MaxDiffCore(middle+1,end,&maxRight,&minRight);

    int crossDiff = maxLeft -minRight;

    *max = (maxLeft>maxRight)?maxLeft:maxRight;//求的每个递归点的值
    *min = (minLeft<minRight)?minLeft:minRight;

    int maxDiff2 = (leftDiff>rightDiff)?leftDiff:rightDiff;

    return (maxDiff2>crossDiff)?maxDiff2:crossDiff;
    }


    int MaxDiff_Solution(int numbers[],unsigned length){
    if(NULL==numbers || length <2)
    return 0;

    int max,min;
    return MaxDiffCore(numbers,numbers+length-1,&max,&min);
    }

    int main(){
    const int N = 10;
    int array[N] = {2,4,1,16,7,5,11,9,5,1};
    cout
    << "MaxDiff: " << MaxDiff_Solution(array,N) << endl;

    return 0;
    }
    运行结果:
    MaxDiff: 15

  • 相关阅读:
    paip.51cto HTML转码规则
    常用记账软件总结
    paip.为什么软件体积越来越大
    paip.版本控制CVSSVNTFS总结
    paip.提升用户体验导入导出
    paip.手机ROOT过程总结
    PAIP.http post 400错误
    paip.javaaspphp.net互相调用方法大总结
    PAip.英文引擎在项目开发上的作用
    paip.SVN无法提交提示冲突的解决
  • 原文地址:https://www.cnblogs.com/phoenixzq/p/2122759.html
Copyright © 2020-2023  润新知