题目描述:
一个无序的实数数组a[i],要求求里面大小相邻的实数的差的最大值。比如 double a[]={1,5,4,0.2,100} 这个无序的数组,相邻的数的最大差值为100-5=95.
题目分析:这题有个简单的做法,首先就是对数组进行一个排序,然后扫面一遍数据就可以得到结果;但时间复杂度依赖于排序时间复杂度,一般为O(nlog n)。
然而一般面试官会让给出一个线性空间和线性时间复杂度的算法。这时就用到了桶排序的思想。
解题思路
解题过程如下:
- 扫面一遍数组,找到数组中的最大max,最小min值。
- 将[min, max]区间平均分为n-1个区间段(每个区间段对应一个桶bucket),每个桶用一对有序实数对[a,b] 来表示桶内的数。
- 再次从头到尾扫描数组,将每个元素添加到相应的桶bucket里面。 注意:有的桶为空(不含任何数据)
- 然后按顺序访问每个(非空)的相邻的桶进行比较。若两个非空的相邻的桶分别为(a,b) , (c,d),那么这两个非空相邻的桶的距离为 c-b。最后选择最大的非空相邻同的距离返回即可。
注意:
- 上述算法是空间和时间复杂度均是O(n)
- 我们不需要计算桶内元素的距离(如b-a),因为数组最大间隔max-min分成n-1个桶,n个元素中一定有两个相邻元素的距离大于桶内的距离(想一想抽屉原理或者鸽巢原理),所以桶内的距离是不用算的
源代码:C++
在算法的实现上,注意桶为空的标记。
此外为了方便,算法实现过程中,桶内保存的不是相应的元素,而是
相应元素在数组中对应的index。
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
/*
*一个无序的实数数组,求它们最近邻的两个值的差
**/
double maxDiff(double a[], int n){
double max = a[0];
double min = a[0];