当前位置: 首页 > news >正文

LeetCode第164题_最大间距

LeetCode 第164题:最大间距

题目描述

给定一个无序的数组 nums,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0 。

您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。

难度

困难

题目链接

点击在LeetCode中查看题目

示例

示例 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 <= 10^5
  • 0 <= nums[i] <= 10^9

解题思路

方法:桶排序

为了满足线性时间和线性空间的要求,我们不能使用基于比较的排序算法。可以使用桶排序或基数排序。这里我们使用桶排序的思想。
关键点:

  1. 计算数组的最大值和最小值
  2. 根据数组长度n,创建n-1个桶
  3. 每个桶记录落在该桶的最大值和最小值
  4. 计算相邻非空桶之间的差值(前一个桶的最大值和后一个桶的最小值之差)
  5. 返回最大的差值

时间复杂度:O(n),其中n是数组长度。
空间复杂度:O(n),需要额外的桶空间。

代码实现

C# 实现

public class Solution {public int MaximumGap(int[] nums) {int n = nums.Length;if (n < 2) return 0;// 寻找最大值和最小值int minVal = nums[0];int maxVal = nums[0];foreach (int num in nums) {minVal = Math.Min(minVal, num);maxVal = Math.Max(maxVal, num);}// 如果最大值等于最小值,则所有元素相同,最大间距为0if (maxVal == minVal) return 0;// 每个桶的大小int bucketSize = Math.Max(1, (maxVal - minVal) / (n - 1));// 桶的数量int bucketCount = (maxVal - minVal) / bucketSize + 1;// 创建桶,每个桶记录最大值和最小值int?[] minBucket = new int?[bucketCount];int?[] maxBucket = new int?[bucketCount];// 将元素放入桶中foreach (int num in nums) {int idx = (num - minVal) / bucketSize;minBucket[idx] = minBucket[idx] == null ? num : Math.Min(minBucket[idx].Value, num);maxBucket[idx] = maxBucket[idx] == null ? num : Math.Max(maxBucket[idx].Value, num);}// 计算相邻非空桶之间的最大差值int maxGap = 0;int prevMax = maxBucket[0].Value;for (int i = 1; i < bucketCount; i++) {// 跳过空桶if (minBucket[i] == null) continue;// 计算当前桶的最小值和前一个非空桶的最大值之差maxGap = Math.Max(maxGap, minBucket[i].Value - prevMax);prevMax = maxBucket[i].Value;}return maxGap;}
}

Python 实现

class Solution:def maximumGap(self, nums: List[int]) -> int:n = len(nums)if n < 2:return 0# 寻找最大值和最小值min_val, max_val = min(nums), max(nums)# 如果最大值等于最小值,则所有元素相同,最大间距为0if max_val == min_val:return 0# 每个桶的大小bucket_size = max(1, (max_val - min_val) // (n - 1))# 桶的数量bucket_count = (max_val - min_val) // bucket_size + 1# 创建桶,每个桶记录最大值和最小值min_bucket = [None] * bucket_countmax_bucket = [None] * bucket_count# 将元素放入桶中for num in nums:idx = (num - min_val) // bucket_sizemin_bucket[idx] = num if min_bucket[idx] is None else min(min_bucket[idx], num)max_bucket[idx] = num if max_bucket[idx] is None else max(max_bucket[idx], num)# 计算相邻非空桶之间的最大差值max_gap = 0prev_max = max_bucket[0]for i in range(1, bucket_count):# 跳过空桶if min_bucket[i] is None:continue# 计算当前桶的最小值和前一个非空桶的最大值之差max_gap = max(max_gap, min_bucket[i] - prev_max)prev_max = max_bucket[i]return max_gap

C++ 实现

class Solution {
public:int maximumGap(vector<int>& nums) {int n = nums.size();if (n < 2) return 0;// 寻找最大值和最小值int minVal = *min_element(nums.begin(), nums.end());int maxVal = *max_element(nums.begin(), nums.end());// 如果最大值等于最小值,则所有元素相同,最大间距为0if (maxVal == minVal) return 0;// 每个桶的大小int bucketSize = max(1, (maxVal - minVal) / (n - 1));// 桶的数量int bucketCount = (maxVal - minVal) / bucketSize + 1;// 创建桶,每个桶记录最大值和最小值vector<pair<int, int>> buckets(bucketCount, {-1, -1}); // {min, max}// 将元素放入桶中for (int num : nums) {int idx = (num - minVal) / bucketSize;if (buckets[idx].first == -1) {buckets[idx].first = buckets[idx].second = num;} else {buckets[idx].first = min(buckets[idx].first, num);buckets[idx].second = max(buckets[idx].second, num);}}// 计算相邻非空桶之间的最大差值int maxGap = 0;int prevMax = buckets[0].second;for (int i = 1; i < bucketCount; i++) {// 跳过空桶if (buckets[i].first == -1) continue;// 计算当前桶的最小值和前一个非空桶的最大值之差maxGap = max(maxGap, buckets[i].first - prevMax);prevMax = buckets[i].second;}return maxGap;}
};

性能分析

各语言实现的性能对比:

实现语言执行用时内存消耗特点
C#140 ms46.2 MB实现清晰,性能适中
Python1712 ms26.4 MB代码简洁,但性能较差
C++132 ms58.5 MB性能最优

补充说明

代码亮点

  1. 使用桶排序思想,满足线性时间和线性空间的要求
  2. 利用鸽巢原理巧妙解决问题
  3. 处理了边界情况,如空数组和所有元素相同的情况

常见错误

  1. 没有正确计算桶的大小和数量
  2. 没有处理边界情况,如空数组和所有元素相同的情况
  3. 没有正确跳过空桶

相关题目

  • 912. 排序数组
  • 1122. 数组的相对排序
  • 274. H指数

相关文章:

  • 图文结合 - 光伏系统产品设计PRD文档 -(慧哥)慧知开源充电桩平台
  • 前端 JavaScript 处理流式响应的坑
  • DeepSeek+Mermaid:轻松实现可视化图表自动化生成(附实战演练)
  • Ubuntu使用war包部署Jenkins并通过systemcl管理
  • 【Java面试笔记:基础】11.Java提供了哪些IO方式? NIO如何实现多路复用?
  • 【Java学习笔记】选择结构
  • ACI multipod 二、IPN (Inter-Pod Network)
  • 【最新版】沃德代驾源码全开源+前端uniapp
  • [蓝桥杯 2025 省 Python B] 异或和
  • IDEA中Quarkus框架(3.13版本)容器编排、压测与调优、注意事项等
  • Python基础语法3
  • 模板方法模式:定义算法骨架的设计模式
  • “在中国,为中国” 英飞凌汽车业务正式发布中国本土化战略
  • 数据的加载与保存
  • 国产三维CAD皇冠CAD在机械及汽车零部件设计建模教程:斜滑动轴承
  • 亚远景-基于ASPICE标准的汽车软件过程优化路径
  • 汽车免拆诊断案例 | 2016款奔驰C200L车组合仪表上多个故障灯偶尔点亮
  • 【AI大模型】MCP:AI应用的“超级扩展坞”
  • 新市场环境下新能源汽车电流传感技术发展前瞻
  • 算法习题-经典环形涂色问题
  • 科普|结石疼痛背后的危机信号:疼痛消失≠警报解除
  • 北京市交通委通报顺平路潮白河大桥事故直接原因
  • 主刀完成3万余例手术,81岁神经外科学专家徐启武逝世
  • 资深翻译家、斯诺研究专家安危逝世,曾为多位外国元首做口译
  • 中国政府援缅第八批紧急人道主义地震救灾物资抵达缅甸
  • 特朗普施压鲍威尔遭多方批评,分析人士:特朗普若解雇鲍威尔或冲击美债