0719. 找出第 K 小的距离对
大约 2 分钟
0719. 找出第 K 小的距离对
- 标签:数组、双指针、二分查找、排序
- 难度:困难
题目链接
题目大意
描述:给定一个整数数组 ,对于数组中不同的数 、 之间的距离定义为 和 的绝对差值,即 。
要求:求所有数对之间第 个最小距离。
说明:
- 。
- 。
- 。
示例:
- 示例 1:
输入:nums = [1,3,1], k = 1
输出:0
解释:数对和对应的距离如下:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
距离第 1 小的数对是 (1,1) ,距离为 0。
- 示例 2:
输入:nums = [1,1,1], k = 2
输出:0
解题思路
思路 1:二分查找算法
一般来说 topK 问题都可以用堆排序来解决。但是这道题使用堆排序超时了。所以需要换其他方法。
先来考虑第 个最小距离的范围。这个范围一定在 之间。
我们可以对 先进行排序,然后得到最小距离为 ,最大距离为 。我们可以在这个区间上进行二分,对于二分的位置 ,统计距离小于等于 的距离对数,并根据它和 的关系调整区间上下界。
统计对数可以使用双指针来计算出所有小于等于 的距离对数目。
- 维护两个指针 、。、 都指向数组开头位置。
- 然后不断移动 ,计算 和 之间的距离。
- 如果大于 ,则 向右移动,直到距离小于等于 时,统计当前距离对数为 。
- 最终将这些符合要求的距离对数累加,就得到了所有小于等于 的距离对数目。
思路 1:代码
class Solution:
def smallestDistancePair(self, nums: List[int], k: int) -> int:
def get_count(dist):
left, count = 0, 0
for right in range(1, len(nums)):
while nums[right] - nums[left] > dist:
left += 1
count += (right - left)
return count
nums.sort()
left, right = 0, nums[-1] - nums[0]
while left < right:
mid = left + (right - left) // 2
if get_count(mid) >= k:
right = mid
else:
left = mid + 1
return left
思路 1:复杂度分析
- 时间复杂度:,其中 为数组 中的元素个数。
- 空间复杂度:,排序算法所用到的空间复杂度为 。