最大间隙问题

来源:互联网 发布:网络图片 侵权 编辑:程序博客网 时间:2024/05/01 09:15

问题描述:最大间隙问题:给定n个实数x1,x2,...,xn,求这n个数在实轴上相邻2个数之间的最大差值。假设对人格实数的下取整函数耗时O(1),设计解最大间隙的问题的线性时间算法。

算法设计:对于给定的n个实数x1,x2,...,xn,计算它们的最大间隙。

数据输入:输入数据由文件名为input.txt的文本文件提供。文件的第一行有一个正整数n,接下来的一行中有n个实数x1,x2,..,xn。

结果输出:将找到的最大间隙输出到文件output.txt。

输入文本示例                        输出样本示例

input.txt                                     output.txt

5                                                3.2

2.3 3.1 7.5 1. 5 6.3


解题思路:

开始时的思想是先排序,再找最大两个的相邻数的差值。但是排序的复杂度最好是O(nlogn),达不到线性。

看了一种方法是利用鸽笼原理,感觉很巧妙,先找到最大和最小数,这步复杂度是O(n),接着做最大最小·值得差,再除以n-1得到n-1的笼子,把除最大最小值的n-2的鸽子放进去,一定有一个笼子是空的,在同一个笼子的间距不可能是最大值,最大值一定在不同的两个笼子中,找到每个笼子的最大值和最小值和鸽子数,从最小的笼子开始找,用后一个有鸽子的笼子的最小值减前面一个有鸽子的笼子的最大值,最后找到最大间距。

main.c

#include<iostream>#include"fileRW.h"#define N 100double MaxCle(int n, double *x);using namespace std;int main(){int num = 0;double data[N];ReadData(&num, data);double maxCle= MaxCle(num, data);WriteData(maxCle);/*cout << num << endl;for (int i = 1; i <= num; i++){cout << data[i] << "  ";}cout << endl;cout << maxCle << endl;system("pause");*/return 0;}// 寻找最小元素的下标template < class  T>int Mini(int n, T *x){T tmp = x[1];int k = 1;for (int i = 1; i <= n; i++){if (x[i] < tmp){tmp = x[i];k = i;}}return k;}// 寻找最大元素的下标template < class  T>int Maxi(int n, T *x){T tmp = x[1];int k = 1;for (int i = 1; i <= n; i++){if (x[i] > tmp){tmp = x[i];k = i;}}return k;}double MaxCle(int n, double *x){// 找到最小最大的值double minx = x[Mini(n, x)];double maxx = x[Maxi(n, x)];//cout << minx << endl;//cout << maxx << endl;int *count = new int[n + 1];double *low = new double[n + 1];double *high = new double[n + 1];// 桶初始化for (int i = 1; i <= n; i++){count[i] = 0;low[i] = maxx;high[i] = minx;}for (int i = 1; i <= n; i++){// 找到每个元素对应的桶号int bucket = int((n - 1) * (x[i] - minx) / (maxx - minx)) + 1;count[bucket]++; // 对应桶的个数增加// 保存每个桶最小的数if (x[i] < low[bucket]){low[bucket] = x[i];}// 保存每个桶最大的元素if (x[i] > high[bucket]){high[bucket] = x[i];}}// 除maxx和minx外的n-2个数放在n-1桶中// 有鸽舍原理知,有一个桶的空的,最大的间隙不会出现在同一个桶中double tmp = 0;double left = high[1];for (int i = 1; i <= n; i++){//cout << count[i] << endl;if (count[i]){double thisgap = low[i] - left;if (thisgap > tmp){tmp = thisgap;left = high[i];}}}return tmp;}

fileRW.c
#include "fileRW.h"// 清空文件void ClearFile(){ofstream ofs;ofs.open("output.txt", ostream::trunc);/*清空文件*/ofs.close(); /*关闭文件*/ofs.clear(); /*清理*/}// 写字符串到文件中void WriteData(double delta){ClearFile();ofstream ofs;ofs.open("output.txt", ostream::app);/*以添加模式打开文件*/ofs << delta << endl; /*写入数据*/ofs.close(); /*关闭文件*/ofs.clear(); /*清理*/}



0 0