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

算法随笔_16: 找出第k小的数对距离

上一篇:算法随笔_15: 找到K个最接近的元素-CSDN博客

题目描述如下

数对 (a,b) 由整数 a 和 b 组成,其数对距离定义为 a 和 b 的绝对差值。给你一个整数数组 nums 和一个整数 k ,数对由 nums[i] 和 nums[j] 组成且满足 0 <= i < j < nums.length 。返回 所有数对距离中 第 k 小的数对距离。

示例 1:

输入:nums = [1,3,1], k = 1
输出:0
解释:数对和对应的距离如下:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
距离第 1 小的数对是 (1,1) ,距离为 0 。

算法思路:

这道题有部分类似于上一篇题目。由于题目要求是找到第k小的数对距离。我们首先要考虑的就是看看能不能把数组做好排序,然后根据排序后的数组想出一些更高效的算法。

如果是暴力解法,我们需要把所有的两两组合都判断一遍,最后找出第k小的数对距离。

当我们把数组进行升序排序之后,我们会发现所有可能数对的距离最大值是数组的头尾两个元素的差,我们把这个最大的距离设为right_vle。那么,所有可能的距离值的范围就在0到right_vle之间。

我们可以先找到此距离范围的中间值mid_vle。小于mid_vle这个距离的所有数对,我们设为pairs_left。大于mid_vle这个距离的那些数对,我们设为pairs_right。

如果pairs_left的数对总个数小于k,说明第k小的数对肯定在pairs_right里。

如果pairs_left的数对总个数大于等于k,说明第k小的数对肯定在pairs_left里。

这就是典型的二分查找的情形。我们可以通过二分查找,不断的缩小区间的范围最终找到第k小的数对距离。

在实际的算法实现中我们仅仅需要设定距离区间的两个边界即可,比如:距离左边界为left_vle,距离右边界为right_vle。可以摒弃掉两个变量pairs_left,pairs_right。下面代码的第17到23行,就是这部分算法的实现。

到目前为止,我们还剩一个步骤需要去做,那就是计算left_vle到right_vle这个区间的所有数对的个数cnt。

此处,我们可以用双指针来解决这个问题。一开始两个指针都同时指向数组的开始,然后先不断的向右移动右指针,同时计算左右指针两个元素的距离

如果距离大于mid_vle,我们需要不断的移动左指针,直到距离小于mid_vle。

如果距离小于mid_vle,此时我们就可以把左右指针之间的元素个数累加到cnt。然后继续移动右指针。

下面代码的fntCnt函数就是实现的此部分算法。

class Solution(object):
    def fndCnt(self,nums,mid_vle):
        cnt=0
        i=0
        n=len(nums)
        for j in range(n):
            while nums[j] - nums[i] > mid_vle:
                i+=1
            cnt += j - i
        return cnt

    def smallestDistancePair(self,nums,k):
        nums.sort()
        left_vle=0
        right_vle=nums[len(nums)-1]-nums[0]
        
        while left_vle<=right_vle:
            mid_vle=(left_vle+right_vle)//2
            cnt=self.fndCnt(nums,mid_vle)
            if cnt< k:
                left_vle=mid_vle+1
            else:
                right_vle=mid_vle-1
        return left_vle
              


http://www.kler.cn/a/515293.html

相关文章:

  • Day 15 卡玛笔记
  • java 根据前端传回的png图片数组,后端加水印加密码生成pdf,返回给前端
  • 内存 管理
  • Hnu电子电路实验2
  • 故障诊断 | BWO白鲸算法优化KELM故障诊断(Matlab)
  • mybatis的多对一、一对多的用法
  • ubuntu扩建swap 解决8295编译卡死的问题(提高系统性能)
  • K8S中Service详解(二)
  • 详解深度学习中的Dropout
  • 数据结构(精讲)----应用篇
  • Dart语言和flutter框架的特性
  • SMT32 FatFs,RTC,记录文件操作时间
  • SentencePiece和 WordPiece tokenization 的含义和区别
  • 备赛蓝桥杯之第十五届职业院校组省赛第二题:分享点滴
  • (1)STM32 USB设备开发-基础知识
  • MDX语言的区块链
  • Mysql面试题----为什么B+树比B树更适合实现数据库索引
  • spring boot中实现手动分页
  • postman请求参数化
  • Rust语言的移动应用开发
  • 考研408笔记之数据结构(三)——串
  • Redis for AI
  • RV1126+FFMPEG推流项目(11)编码音视频数据 + FFMPEG时间戳处理
  • springboot网上书城
  • android studio本地打包后,无法热更,无法执行换包操作,plus.runtime.install没有弹窗
  • 提升 Go 开发效率的利器:calc_util 工具库