本人最近在上算法课,所以偶尔会分享一些知识点和代码。预估本人会比较懒,所以可能不会写的很完整,不过关键的地方一定会尽量写清楚。而写博客算是给自己一个小小的鼓励吧。如果有幸能给你提供一点小小的帮助,本人也会很开心~~~今天分享比较简单的最大间隙问题,运用鸽舍原理。
#include<iostream>
using namespace std;
template <class T>
int maxi(int n, double *T) {
int k = 0;
double tmp = T[0];
for (int i = 1; i < n; ++i) {
if (tmp > T[i]) {
tmp = T[i];
k = i;
}
}
return k;
}
template <class T>
int mini(int n, double *T) {
int k = 0;
double tmp = T[0];
for (int i = 0; i < n; ++i) {
if (tmp < T[i]) {
tmp = T[i];
k = i;
}
}
return k;
}
int maxGap(int n, double *T) {
double minx = T[mini(n, T)], maxx = T[maxi(n, T)];
//桶的参数,count-第count个桶;low-第count个桶中的最小值,high-第count个桶中的最大值
int *count = new int[n + 1];
int *low = new int[n + 1];
int *high = new int[n + 1];
//桶初始化
for (int i = 0; i < n; ++i) {
count[i] = 0;
low[i] = maxx;
high[i] = minx;
}
//记录每个桶里面的元素个数,并找出每个桶中最大和最小的元素
for (int i = 0; i < n; ++i) {
int bucket = int((T[i] - minx) / (maxx - minx)) + 1; //判断T[i]属于哪个桶
count[bucket]++;
if (T[i] > high[bucket]) {
high[bucket] = T[i];
}
if (T[i] < low[bucket]) {
low[bucket] = T[i];
}
}
//对所有的桶进行线性排序,找出最大间隙
double tmp = 0, left = high[1];
for (int i = 2; i < n - 1; ++i) {
if(count[i]) { // 第i个桶里面有数据
int thisgap = low[i] - left; //用第i个桶里面的最小值减去上一个有元素桶里面的最大值
if(thisgap > tmp) {
tmp = thisgap;
left = high[i]; //下次作差时,需要减去high[i]
}
}
}
return tmp; //最大间隙
}
int main() {
int n = 10;
double a[10] = {10, 3, 11, 2, 6, 7, 9,1, 8, 4};
/*最大间隙问题不要求元素初始有序,它是在乱序的情况下,对所有的元素逻辑上分配到每个桶中,只需记录每个桶中最大最小元素即可。
*然后计算每个桶中的最大元素和下一个有元素的桶中最小元素之间的距离
*
* 在[minx,maxx]内的n个元素,平均分为n-1个等长度的份,剩余的n-2个元素被分配在这n-1个桶中,必然会有一个桶里面没有元素,
* 因此最大间隙一定是某一个桶的最小元素减去上一个有元素的桶中的最大元素
*/
double gap = maxGap(n, a);
cout << "maxGap " << gap << endl;
return 0;
}