LeetCode每日一题2025-06-13
2616. 最小化数对的最大差值 M
给你一个下标从 0 开始的整数数组 nums 和一个整数 p 。请你从 nums 中找到 p 个下标对,每个下标对对应数值取差值,你需要使得这 p 个差值的 最大值 最小。同时,你需要确保每个下标在这 p 个下标对中最多出现一次。
对于一个下标对 i 和 j ,这一对的差值为 |nums[i] - nums[j]| ,其中 |x| 表示 x 的 绝对值 。
请你返回 p 个下标对对应数值 最大差值 的 最小值 。
示例 1:
输入:nums = [10,1,2,7,1,3], p = 2
输出:1
解释:第一个下标对选择 1 和 4 ,第二个下标对选择 2 和 5 。
最大差值为 max(|nums[1] - nums[4]|, |nums[2] - nums[5]|) = max(0, 1) = 1 。所以我们返回 1 。
示例 2:
输入:nums = [4,2,1,2], p = 1
输出:0
解释:选择下标 1 和 3 构成下标对。差值为 |2 - 2| = 0 ,这是最大差值的最小值。
提示:
1 <= nums.length <= 10⁵0 <= nums[i] <= 10⁹0 <= p <= (nums.length)/2
问题分析
给定长度为 的整数数组 和整数 ,需要从中选出 对不重叠下标,使得这 对中差值的最大值最小。
- 差值定义:对一对下标 ,差值为 。
- 每个下标最多只能出现一次。
关键在于:若假设“最大差值”上限为 ,能否在所有相邻差值 的情况下选出至少 对?
若可行,则可通过二分搜索最小的 。
算法思路
-
排序
将 排序为 ,令 。 -
定义可行性检查
对给定阈值 ,我们从左到右贪心配对相邻元素:1
2
3
4
5
6
7
8cnt = 0, i = 0
while i < n-1 and cnt < p:
if A[i+1] - A[i] ≤ D:
cnt += 1
i += 2 # 已用 i 和 i+1
else:
i += 1
return cnt ≥ p若能配出 ≥ 对,则
D可行。 -
二分答案
- 左边界
- 右边界
- 不断令 ,检查可行性;
- 若可行,则将 ,并记录答案;
- 否则 。
结束时 即为最小可行最大差值。
时间复杂度
- 排序:
- 二分搜索:答案范围 ,需 轮,每轮贪心扫描
- 总体:
其中 。
代码分解
1.预处理
- 对
nums排序。
2.can_make(mid) 函数
- 输入:差值上限
mid - 输出:布尔值,表示能否在该上限下配出 ≥ 对。
- 逻辑:贪心配对相邻差值
mid的元素。
3.二分查找主流程
- 初始化 , 。
- 循环直至 ,更新边界并记录可行答案。
4.返回结果
- 最终的最小可行差值。
代码实现
1 | from typing import List |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Stay hungry. Stay foolish.!
评论
