数组排序后相邻数的最大差值
一、题目
给定一个无序的数组 nums,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0 。
您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。
Leetcode:https://leetcode.cn/problems/maximum-gap/
二、思路
利用桶排序的思路,以下思路步骤
先获取到数组的最大值 max、最小值 min、以及数组的长度 N。用于确定桶的区间范围。接下来我们申请一个桶,桶的长度为 N+1。然后将数组中的元素填充到桶中。因为桶的个数为 N+1,所以必定有一个以上的空桶。
我们要求的是相邻数的最大差值,桶内的两个元素之间的最大差值肯定小于桶的区间范围。中间为空桶,两边非空桶的最大差值即为我们想要求的最大差值。因此我们发现我们桶中只需要保存当前桶中的最大值和最小值。整个数组中的最大差值为,空桶后的那个非空桶的最小值,减去,空桶前的那个非空桶的最大值。
我们设置桶的个数为 N+1,就是为了构造空桶。那么桶中的元素范围应该如何确定呢?答案就是 (max - min) / N
。某个元素想要插入桶中,应该插入那个桶呢?应该是 (num - min) / ( (max - min) / N )
。而且我们想要的是数组的最小值插入到第一个桶中,数组中最大值插入到最后一个桶中。保证空桶在中间。
因此 (num - min) / ( (max - min) / N )
这个表达式无法保证数组的最大值插入到最后一个桶中,因为 (max - min)
的值如果小于 N 的话,会使 (max-min)/N
的值永远为 0。因为我们转换为 (num - min) * N / (max - min)
。这样,我们就可以保证数组的最大值插入到最后一个桶中。
三、代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| #include <vector> #include <iostream>
class Solution { public: int get_max_gap(const std::vector<int>& nums) { if (nums.empty() || nums.size() == 1) { return 0; } int max = INT32_MIN, min = INT32_MAX; for (const auto& x : nums) { if (x > max) { max = std::max(max, x); } if (x < min) { min = std::min(min, x); } } int count = nums.size(); std::vector<std::pair<int, int>> bucket(count+1, {INT32_MIN, INT32_MAX}); for (const auto& x : nums) { int bucket_id = get_bucket_id(max, min, x, count); int tmp_max = bucket[bucket_id].first; int tmp_min = bucket[bucket_id].second; bucket[bucket_id].first = std::max(tmp_max, x); bucket[bucket_id].second = std::min(tmp_min, x); } int pre_max = INT32_MIN; int res_max = 0; bool flag = false; for (const auto& x : bucket) { if (x.first != INT32_MIN || x.second != INT32_MAX) { if (flag == true) { res_max = std::max(res_max, x.second - pre_max); flag = false; } pre_max = x.first; } else { flag = true; } } return res_max; }
int get_bucket_id(int64_t max, int64_t min, int64_t num, int64_t count) { int id = 0; if (max - min != 0) { id = (num - min) * count / (max - min); } return id; } };
int main() { Solution s; std::vector<int> arr{1, 1, 1, 1, 1, 5, 5, 5, 5, 5}; auto res = s.get_max_gap(arr); std::cout << res << std::endl; return 0; }
|
时间复杂度:O(N)
,空间复杂度为:O(N)