问题链接
719. 找出第 K 小的数对间隔
问题形貌
数对 (a,b) 由整数 a 和 b 组成,其数对间隔界说为 a 和 b 的绝对差值。
给你一个整数数组 nums 和一个整数 k ,数对由 nums 和 nums[j] 组成且满足 0 <= i < j < nums.length 。返回 全部数对间隔中 第 k 小的数对间隔。
提示:
- n == nums.length
- 2 <= n <= 104
- 0 <= nums <= 106
- 1 <= k <= n * (n - 1) / 2
示例
示例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示例3输入:nums = [1,6,1], k = 3输出:5解题思绪
看一下提示的范围,就知道暴力破解直接没戏~
这道题,可以对数对间隔的域值举行二分查找解题。
- 先对数组nums排序;
- 对数对间隔的域值举行二分查找:
A. 初始left为0,right为数组头尾相减的绝对值,middle为left与right和的一半;
B. 统计全部间隔小于便是 middle 的数对数量,记为count;
C. 如果count大于便是k,right = middle - 1;反之,left = middle + 1;
D. 如果left小于便是right,继承以上利用;
- 当left大于right时,返回效果left。
代码示例(JAVA)
class Solution { public int smallestDistancePair(int[] nums, int k) { // 先辈行排序 Arrays.sort(nums); // 值域二分找k int length = nums.length; int left = 0, right = nums[length - 1] - nums[0]; while (left <= right) { int middle = (right + left) / 2; int count = countPair(nums, middle); if (count >= k) { right = middle - 1 ; } else { left = middle + 1; } } return left; } // 统计数对 public int countPair(int[] nums, int value) { int count = 0; for (int i = 0; i < nums.length - 1; i++) { for (int j = i + 1; j < nums.length; j++) { if (nums[j] - nums <= value) { count++; } else { break; } } } return count; }}实验效果
|