算法设计与分析 作业 算法实现 1
问题描述
最大间隙问题。给定 n 个实数x1 , x2 ,…,xn,求这n个 实数在数轴上相邻2个数之间的最大差值。
直观解法:将n个数排序后计算间距,再找最大值。 假设对任何实数的下取整函数耗时O(1), 设计解最大间隙问题的线性时间算法。
算法输入: 输入数据由文件名input.txt的文本提供。文件的第一 行有一个正整数n,接下来有n个实数。
算法输出: 将找到的最大间隙输出到文件output.txt中。
设:
- 最小值
minv
- 最大值
maxv
- n 个实数
则整体区间长度为:
range = maxv - minv
如果把区间分成 n-1
个桶(bucket),
每个桶宽度:
gap = range / (n - 1)
由于最大间隙必然发生在 相邻非空桶 之间(而非桶内),
我们只需要每个桶记录:
桶最小值
桶最大值
(空桶跳过)
然后:
max_gap = max(next_bucket.min - prev_bucket.max )
1️⃣ 扫描一次找到 minv
和 maxv
2️⃣ 若所有数相等,最大间隙为 0
3️⃣ 计算桶宽度:
gap = (maxv - minv) / (n - 1)
4️⃣ 建立 n−1 个桶,每个桶记录:
struct Bucket {
bool used = false;
double minval = std::numeric_limits<double>::infinity();
double maxval = -std::numeric_limits<double>::infinity();
};
5️⃣ 遍历每个数 x
:
if (x == maxv) idx = n - 2; // 特殊处理最大值
else idx = int((x - minv) / gap);
更新该桶的 minval
与 maxval
。
6️⃣ 再遍历桶,计算最大间隙:
max_gap = max(curr.minval - prev.maxval)
7️⃣ 源码
#include <iostream>
#include <fstream>
#include <vector>
#include <limits>
#include <cmath>struct Bucket {bool used = false;double minval = std::numeric_limits<double>::infinity();double maxval = -std::numeric_limits<double>::infinity();
};int main() {std::ifstream fin("input.txt");if (!fin) {std::cerr << "Error: cannot open input.txt\n";return 1;}int n;fin >> n;if (n <= 1) {std::ofstream("output.txt") << 0.0;return 0;}std::vector<double> nums(n);for (int i = 0; i < n; ++i)fin >> nums[i];fin.close();double minv = nums[0], maxv = nums[0];for (double x : nums) {if (x < minv) minv = x;if (x > maxv) maxv = x;}if (minv == maxv) {std::ofstream("output.txt") << 0.0;return 0;}double gap = (maxv - minv) / (n - 1);std::vector<Bucket> buckets(n - 1);for (double x : nums) {int idx = (x == maxv) ? (n - 2) : int((x - minv) / gap);auto &b = buckets[idx];b.used = true;if (x < b.minval) b.minval = x;if (x > b.maxval) b.maxval = x;}double max_gap = 0;double prev_max = minv;for (const auto &b : buckets) {if (!b.used) continue;max_gap = std::max(max_gap, b.minval - prev_max);prev_max = b.maxval;}std::ofstream fout("output.txt");fout << max_gap;fout.close();return 0;
}