164. 最大间距
给定一个无序的数组 nums
,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0
。
您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。
示例 1:
输入: nums = [3,6,9,1] 输出: 3 解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
示例 2:
输入: nums = [10] 输出: 0 解释: 数组元素个数小于 2,因此返回 0。
提示:
1 <= nums.length <= 105
0 <= nums[i] <= 109
原站题解
python3 解法, 执行用时: 1532 ms, 内存消耗: 28.5 MB, 提交时间: 2023-06-21 18:06:36
# 基数排序 class Solution: def maximumGap(self, nums: List[int]) -> int: if len(nums) < 2: return 0 # 极端情况 # 基数排序 i = 0 # 记录当前正在排拿一位,最低位为1 max_num = max(nums) # 最大值 j = len(str(max_num)) # 记录最大值的位数 while i < j: bucket_list =[[] for _ in range(10)] #初始化桶数组 for x in nums: bucket_list[int(x / (10**i)) % 10].append(x) # 找到位置放入桶数组 nums.clear() for x in bucket_list: # 放回原序列 for y in x: nums.append(y) i += 1 return max(nums[i] - nums[i-1] for i in range(1, len(nums)))
python3 解法, 执行用时: 1128 ms, 内存消耗: 30.6 MB, 提交时间: 2023-06-21 18:06:10
# 基数排序 class Solution: def maximumGap(self, nums: List[int]) -> int: if len(nums) == 1: return 0 m = len(str(max(nums))) #获取最高位数 last_layer = [nums] for i in range(m): this_layer = [[] for _ in range(10)] for j in last_layer: for k in j: #按顺序将m-1位的处理结果(last_layer)重新装到m位的结果中(this_layer) num = (k // (10**i)) % 10 this_layer[num].append(k) last_layer = this_layer[:] dummy = [] #按顺序填入排序好的数字 for i in last_layer: for j in i: dummy.append(j) result = 0 for i in range(len(dummy)-1): result = max(result,dummy[i+1] - dummy[i]) return result
java 解法, 执行用时: 45 ms, 内存消耗: 59.2 MB, 提交时间: 2023-06-21 18:05:08
class Solution { public int maximumGap(int[] nums) { int n = nums.length; if (n < 2) { return 0; } int minVal = Arrays.stream(nums).min().getAsInt(); int maxVal = Arrays.stream(nums).max().getAsInt(); int d = Math.max(1, (maxVal - minVal) / (n - 1)); int bucketSize = (maxVal - minVal) / d + 1; int[][] bucket = new int[bucketSize][2]; for (int i = 0; i < bucketSize; ++i) { Arrays.fill(bucket[i], -1); // 存储 (桶内最小值,桶内最大值) 对, (-1, -1) 表示该桶是空的 } for (int i = 0; i < n; i++) { int idx = (nums[i] - minVal) / d; if (bucket[idx][0] == -1) { bucket[idx][0] = bucket[idx][1] = nums[i]; } else { bucket[idx][0] = Math.min(bucket[idx][0], nums[i]); bucket[idx][1] = Math.max(bucket[idx][1], nums[i]); } } int ret = 0; int prev = -1; for (int i = 0; i < bucketSize; i++) { if (bucket[i][0] == -1) { continue; } if (prev != -1) { ret = Math.max(ret, bucket[i][0] - bucket[prev][1]); } prev = i; } return ret; } }
javascript 解法, 执行用时: 268 ms, 内存消耗: 74.8 MB, 提交时间: 2023-06-21 18:04:52
/** * @param {number[]} nums * @return {number} */ var maximumGap = function(nums) { const n = nums.length; if (n < 2) { return 0; } const minVal = Math.min(...nums); const maxVal = Math.max(...nums); const d = Math.max(1, Math.floor(maxVal - minVal) / (n - 1)); const bucketSize = Math.floor((maxVal - minVal) / d) + 1; const bucket = new Array(bucketSize).fill(0).map(x => new Array(2).fill(0)); for (let i = 0; i < bucketSize; ++i) { bucket[i].fill(-1); } for (let i = 0; i < n; i++) { const idx = Math.floor((nums[i] - minVal) / d); if (bucket[idx][0] === -1) { bucket[idx][0] = bucket[idx][1] = nums[i]; } else { bucket[idx][0] = Math.min(bucket[idx][0], nums[i]); bucket[idx][1] = Math.max(bucket[idx][1], nums[i]); } } let ret = 0; let prev = -1; for (let i = 0; i < bucketSize; i++) { if (bucket[i][0] == -1) { continue; } if (prev != -1) { ret = Math.max(ret, bucket[i][0] - bucket[prev][1]); } prev = i; } return ret; };
golang 解法, 执行用时: 116 ms, 内存消耗: 10 MB, 提交时间: 2023-06-21 18:04:35
// 桶排序 type pair struct{ min, max int } func maximumGap(nums []int) (ans int) { n := len(nums) if n < 2 { return } minVal := min(nums...) maxVal := max(nums...) d := max(1, (maxVal-minVal)/(n-1)) bucketSize := (maxVal-minVal)/d + 1 // 存储 (桶内最小值,桶内最大值) 对,(-1, -1) 表示该桶是空的 buckets := make([]pair, bucketSize) for i := range buckets { buckets[i] = pair{-1, -1} } for _, v := range nums { bid := (v - minVal) / d if buckets[bid].min == -1 { buckets[bid].min = v buckets[bid].max = v } else { buckets[bid].min = min(buckets[bid].min, v) buckets[bid].max = max(buckets[bid].max, v) } } prev := -1 for i, b := range buckets { if b.min == -1 { continue } if prev != -1 { ans = max(ans, b.min-buckets[prev].max) } prev = i } return } func min(a ...int) int { res := a[0] for _, v := range a[1:] { if v < res { res = v } } return res } func max(a ...int) int { res := a[0] for _, v := range a[1:] { if v > res { res = v } } return res }
golang 解法, 执行用时: 144 ms, 内存消耗: 8.7 MB, 提交时间: 2023-06-21 18:04:13
func maximumGap(nums []int) (ans int) { n := len(nums) if n < 2 { return } buf := make([]int, n) maxVal := max(nums...) for exp := 1; exp <= maxVal; exp *= 10 { cnt := [10]int{} for _, v := range nums { digit := v / exp % 10 cnt[digit]++ } for i := 1; i < 10; i++ { cnt[i] += cnt[i-1] } for i := n - 1; i >= 0; i-- { digit := nums[i] / exp % 10 buf[cnt[digit]-1] = nums[i] cnt[digit]-- } copy(nums, buf) } for i := 1; i < n; i++ { ans = max(ans, nums[i]-nums[i-1]) } return } func max(a ...int) int { res := a[0] for _, v := range a[1:] { if v > res { res = v } } return res }
javascript 解法, 执行用时: 156 ms, 内存消耗: 62.3 MB, 提交时间: 2023-06-21 18:03:38
/** * @param {number[]} nums * @return {number} */ var maximumGap = function(nums) { const n = nums.length; if (n < 2) { return 0; } let exp = 1; const buf = new Array(n).fill(0); const maxVal = Math.max(...nums); while (maxVal >= exp) { const cnt = new Array(10).fill(0); for (let i = 0; i < n; i++) { let digit = Math.floor(nums[i] / exp) % 10; cnt[digit]++; } for (let i = 1; i < 10; i++) { cnt[i] += cnt[i - 1]; } for (let i = n - 1; i >= 0; i--) { let digit = Math.floor(nums[i] / exp) % 10; buf[cnt[digit] - 1] = nums[i]; cnt[digit]--; } nums.splice(0, n, ...buf); exp *= 10; } let ret = 0; for (let i = 1; i < n; i++) { ret = Math.max(ret, nums[i] - nums[i - 1]); } return ret; };
java 解法, 执行用时: 38 ms, 内存消耗: 55.2 MB, 提交时间: 2023-06-21 18:03:16
class Solution { public int maximumGap(int[] nums) { int n = nums.length; if (n < 2) { return 0; } long exp = 1; int[] buf = new int[n]; int maxVal = Arrays.stream(nums).max().getAsInt(); while (maxVal >= exp) { int[] cnt = new int[10]; for (int i = 0; i < n; i++) { int digit = (nums[i] / (int) exp) % 10; cnt[digit]++; } for (int i = 1; i < 10; i++) { cnt[i] += cnt[i - 1]; } for (int i = n - 1; i >= 0; i--) { int digit = (nums[i] / (int) exp) % 10; buf[cnt[digit] - 1] = nums[i]; cnt[digit]--; } System.arraycopy(buf, 0, nums, 0, n); exp *= 10; } int ret = 0; for (int i = 1; i < n; i++) { ret = Math.max(ret, nums[i] - nums[i - 1]); } return ret; } }
cpp 解法, 执行用时: 204 ms, 内存消耗: 83.6 MB, 提交时间: 2023-06-21 18:03:01
// 基数排序 class Solution { public: int maximumGap(vector<int>& nums) { int n = nums.size(); if (n < 2) { return 0; } int exp = 1; vector<int> buf(n); int maxVal = *max_element(nums.begin(), nums.end()); while (maxVal >= exp) { vector<int> cnt(10); for (int i = 0; i < n; i++) { int digit = (nums[i] / exp) % 10; cnt[digit]++; } for (int i = 1; i < 10; i++) { cnt[i] += cnt[i - 1]; } for (int i = n - 1; i >= 0; i--) { int digit = (nums[i] / exp) % 10; buf[cnt[digit] - 1] = nums[i]; cnt[digit]--; } copy(buf.begin(), buf.end(), nums.begin()); exp *= 10; } int ret = 0; for (int i = 1; i < n; i++) { ret = max(ret, nums[i] - nums[i - 1]); } return ret; } };
python3 解法, 执行用时: 564 ms, 内存消耗: 33.3 MB, 提交时间: 2023-06-21 18:00:35
# 桶排序 class Solution: def maximumGap(self, nums: List[int]) -> int: if len(nums) < 2: return 0 # 一些初始化 max_ = max(nums) min_ = min(nums) max_gap = 0 each_bucket_len = max(1,(max_-min_) // (len(nums)-1)) buckets =[[] for _ in range((max_-min_) // each_bucket_len + 1)] # 把数字放入桶中 for i in range(len(nums)): loc = (nums[i] - min_) // each_bucket_len buckets[loc].append(nums[i]) # 遍历桶更新答案 prev_max = float('inf') for i in range(len(buckets)): if buckets[i] and prev_max != float('inf'): max_gap = max(max_gap, min(buckets[i])-prev_max) if buckets[i]: prev_max = max(buckets[i]) return max_gap