每日算法系列【LeetCode 719】找出第 k 小的距离对
题目描述
给定一个整数数组,返回所有数对之间的第 k 个最小距离。一对 (A, B) 的距离被定义为 A 和 B 之间的绝对差值。
示例1
输入:
nums = [1,3,1]
k = 1
输出:
0
解释:
所有数对如下:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
因此第 1 个最小距离的数对是 (1,1),它们之间的距离为 0。
提示
- 2 <= len(nums) <= 10000.
- 0 <= nums[i] < 1000000.
- 1 <= k <= len(nums) * (len(nums) - 1) / 2.
题解
注意到这题 比较大,所以不能算出所有的数对差值,然后排序,这样时间复杂度就是 了。
直觉上应该先给数组从小到大排个序,那么差值最小值就是 0 ,最大值就是 ,答案肯定也就在这个区间里了。
那么我们可以从最大的差值开始,看是否有数对满足这个差值,并且这个差值还得是第 小的。对于差值 ,如果它是第 小的,说明所有数对中差值小于等于 的数对个数 一定大于等于 。因为如果第 小的差值只有一个数对满足,那么 ,否则的话就有多个数对差值都是 ,那就有 。于是我们找到第一个满足 的差值就行了,再加 1 就是最终的答案。
那么怎么求小于等于 的数对个数 呢?因为排过序了,所以可以采用双指针的方法,初始时 ,对于每个右指针 ,我们移动左指针 ,直到 。那么最终 就是以 作为较大数的数对个数。因为两个指针都是向右移动的,所以每次计算个数只需要 的时间复杂度。
所以这个方法最终总的时间复杂度为 ,因为最大差值 还是太大,所以还是没有办法直接遍历。
又注意到随着 的减小, 也是单调减小的,所以可以二分寻找 。如果 ,那么说明答案小于等于 ,于是令 。如果 ,那么说明答案一定大于 ,于是令 ,最终答案就是 。
这样二分优化之后,最终的时间复杂度为 ,可以接受。
代码
c++
class Solution {public:int smallestDistancePair(vector<int>& nums, int k) {int n = nums.size();sort(nums.begin(), nums.end());int l = 0, r = nums[n-1]-nums[0];while (l < r) {int m = (l + r) / 2;if (count(m, nums) >= k) r = m;else l = m + 1;}return l;}int count(int K, vector<int>& nums) {int cnt = 0, l = 0, n = nums.size();for (int r = 0; r < n; ++r) {while (l < r && nums[r]-nums[l] > K) {l++;}cnt += r - l;}return cnt;}
};
python
class Solution:def smallestDistancePair(self, nums: List[int], k: int) -> int:n = len(nums)nums.sort()def count(K: int) -> int:cnt, l = 0, 0for r in range(n):while l < r and nums[r]-nums[l] > K:l += 1cnt += r - lreturn cntl, r = 0, nums[-1]-nums[0]while l < r:m = (l + r) // 2if count(m) >= k:r = melse:l = m + 1return l
每日算法系列【LeetCode 719】找出第 k 小的距离对相关推荐
- LeetCode 719. 找出第 K 小的数对距离
719. 找出第 K 小的数对距离 [二分+二分] 首先对数组排序,然后算出最大值和最小值之间的差值,这个差值就是解空间的最大值,然后对解空间进行二分,每次对解空间的mid统计数对距离小于他的个数,通 ...
- 在两个已经排好序的数组里找出第K小的数
前言: 这道题是一道非常常见的面试题,也是一道能够考察一个人的编程能力和算法的一道题.如果要求复杂度为 O(k), 是比较容易做出来的,但是,一般来讲,面试官要求给出更低复杂度的算法.网上有很多不同的 ...
- LeetCode 1738. 找出第 K 大的异或坐标值(DP)
文章目录 1. 题目 2. 解题 947 / 3851,前 24.6% 2533 / 11282,前 22.5% 1. 题目 给你一个二维矩阵 matrix 和一个整数 k ,矩阵大小为 m x n ...
- leetcode 1738. 找出第 K 大的异或坐标值
本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接 题目 给你一个二维矩阵 matrix 和一个整数 k ,矩阵大小为 m x n 由非负整数组成. 矩阵中坐标 (a, b) ...
- 数字n,按字典排序,找出第k小的数字
(1)首先列出所有的字典序,然后选择第k个 class Solution { public: bool static compare(int a,int b) { re ...
- 重复次数最多的 子串_每日算法系列【LeetCode 424】替换后的最长重复字符
题目描述 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 示例1 输入: s = &quo ...
- LeetCode 2028. 找出缺失的观测数据
文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 三.本题小知识 四.加群须知 一.题目 1.题目描述 现有一份 n + m次 ...
- LeetCode 2058. 找出临界点之间的最小和最大距离
文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 三.本题小知识 四.加群须知 一.题目 1.题目描述 链表中的 临界点 定义 ...
- 约瑟夫环——递推公式详解(leetcode 1823. 找出游戏的获胜者)
约瑟夫环--递推公式详解(leetcode 1823. 找出游戏的获胜者) 约瑟夫环问题 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知 n 个人(以编号1,2,3-n分别表示)围坐在一张圆桌周围. ...
- LeetCode 1823. 找出游戏的获胜者
LeetCode 1823. 找出游戏的获胜者 文章目录 LeetCode 1823. 找出游戏的获胜者 题目描述 一.解题关键词 二.解题报告 1.思路分析 2.时间复杂度 3.代码示例 2.知识点 ...
最新文章
- jackson 反序列化string_java – 使用Jackson对数组进行反序列化
- NPashaP的二分图源码部分
- 使用vue控制元素显示隐藏
- Redis运维和开发学习笔记(7) 内存管理和过期策略
- 【并查集+dp】Team
- 韩国出现加密货币妈妈潮 女性对加密投资兴趣趋升
- Linux 下 Tomcat Https
- Global.asax取绝对路径
- socket数据的发送和接收
- svn的安装包和中文语言包下载
- JAVA基础篇——JAVA运行环境(JDK、JRE、JVM)
- python输出艺术字_Python中输出ASCII大文字、艺术字、字符字小技巧
- 计算机科学研究的第一手段,实验研究类论文的研究方法(11种研究方法解析)...
- 平肝息风药题库【1】
- EXCEL与数据分析
- linux怎么看网络连接网络,linux如何查看网络连接情况?
- 二维数组更改vue,VueX中直接修改数据报错,修改一维数组,二维数组,报错的原因...
- 计算机专业854,精选-2017年哈工大计算机科学与技术专业854考研真题
- element UI 修改 table 中某一列的值
- 谈一谈mmkv的使用
热门文章
- CXF(2.7.10) - RESTful Services, JSON Support
- Google Map API v2 (三)----- 地图上添加标记(Marker),标记info窗口,即指定经纬度获取地址字符串...
- Json.net说法——(四)序列化错误处理
- 丢失更新的问题产生和解决
- vue组件(将页面公用的头部组件化)
- android 抽屉式滑动demo
- 关于jstl EL用法的注意点(java.lang.NumberFormatException: For input string: userName)
- SQL 语句 - Select(2): 指定表中的字段
- 从北京站到天通苑怎么走,
- [原] 求薪水第三高的雇员的SQL题(图解)