力扣373. 查找和最小的 K 对数字 优先队列法

news2024/12/28 19:05:57

题目

给定两个以 非递减顺序排列 的整数数组 nums1 和 nums2 , 以及一个整数 k 。

定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2 。

请找到和最小的 k 个数对 (u1,v1), (u2,v2) … (uk,vk) 。

示例 1:

输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
输出: [1,2],[1,4],[1,6]
解释: 返回序列中的前 3 对数:
     [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]

示例 2:

输入: nums1 = [1,1,2], nums2 = [1,2,3], k = 2
输出: [1,1],[1,1]
解释: 返回序列中的前 2 对数:
     [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]

示例 3:

输入: nums1 = [1,2], nums2 = [3], k = 3 
输出: [1,3],[2,3]
解释: 也可能序列中所有的数对都被返回:[1,3],[2,3]

提示:

1 <= nums1.length, nums2.length <= 10^5
-10^9 <= nums1[i], nums2[i] <= 10^9
nums1 和 nums2 均为升序排列
1 <= k <= 10^4

优先队列思路

一开始想的太简单了,错误思路:不能把俩个数组里的全部数的组合都放小根堆里去,因为俩个数组的最大容量是10^ 5,那么所有组合的最大数量为10^10 肯定会爆内存。

那么如何优化? 关键是题目已经给出俩个数组都是升序的。首先nums1[0]和nums1[0]肯定是最小的组合,次小的组合肯定是(nums1[1],nums1[0])或者(nums1[0],nums1[1])。因为俩个数组都是升序,所以(nums1[1],nums1[1])>=(nums1[1],nums1[0])、(nums1[0],nums1[1])
所以我们可以把前面较小的一部分组合的下标放入小根堆,然后根据下标对应的值的大小来排序,如果(i,j)下标对应的值此时是最小的,就把其取出存入答案链表,并把次小(i+1,j)、(i,j+1)下标放入小根堆。
但是这样有问题,就是(i,j+1)和(i+1,j)被取出时都会加入(i+1,j+1),导致这个坐标被重复加入了,所以我们可以改变思路,当(i,j)此时是最小的,就把其取出,只把次小(i,j+1)放入小根堆,至于(i+1,j) 则等当取出(i+1,j-1)时再加入。
这种取法要求我们一开始就往小根堆加入(0,0),(1,0)…,(m,0),这样才能保证所有的点位能够被加入。

用图解来看就是,从下面这张图的策略转为下下张图的策略。
请添加图片描述

请添加图片描述

代码:

public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        PriorityQueue<int[]>priorityQueue=new PriorityQueue<>((o1,o2)->
                nums1[o1[0]]+nums2[o1[1]]-nums1[o2[0]]-nums2[o2[1]]);//自定义排序小根堆 lambda写法
        int m=nums1.length,n=nums2.length;
        for (int i = 0; i < Math.min(m,k); i++) {//Math.min(m,k)是优化写法 如果k>=m则不用说 第一列全加入就好了
            priorityQueue.add(new int[]{nums1[i],nums2[0]});//当k<m 只加到第k行就行了 这是为什么呢?
        }//因为只要求前k小 前k行包括的可能性肯定足够了 再往下的行都比前面的大 不可能是答案
        List<List<Integer>> list=new ArrayList<>();
        for (int i = 0; i < k; i++) {
            int []o=priorityQueue.poll();
            list.add(new ArrayList<>(Arrays.asList(nums1[o[0]],nums2[o[1]])));
            if(o[1]+1<n) priorityQueue.add(new int[]{o[0],o[1]+1});
            if(priorityQueue.isEmpty()) break;
        }
        return list;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/982244.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BFGS算法python实现

文章目录 Python代码当前参数下求解结果参数设置 Python代码 import scipy import numpy as np import matplotlib.pyplot as plt from scipy.optimize import minimize def func(x):return 7*np.sin(x) 11*np.cos(5*x) def cal_func():x np.linspace(-5,5,1000)y func(x)r…

【电压质量】提高隔离电源系统的电压质量(Simulink实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

嵌入式学习笔记(17)代码重定位实战 上篇

3.5.1任务&#xff1a;在iSRAM中将代码从0xd0020010重定位到0xd0024000 注解&#xff1a;本练习对代码本身运行无实际意义&#xff0c;我们做这个重定位纯粹是为了练习重定位技能。但是某些情况重定位就是必须的&#xff0c;譬如在uboot中。 3.5.2思路 &#xff08;1&#xff…

2023新疆褐牛产业集群高质量发展论坛伊犁召开

8月31日&#xff0c;“2023新疆褐牛产业集群高质量发展论坛”在新疆巩留县召开&#xff0c;相关部委、权威专家和企业代表欢聚一堂&#xff0c;共商新疆褐牛科学化繁育和规模化养殖之路&#xff0c;共享新疆褐牛一二三产业融合发展创新模式&#xff0c;助力新疆褐牛产业集群发展…

知识库建设:从0到1搞定知识库建设的方法论分享

如果我们想要搭建一个知识库&#xff0c;前提是我们要明确知道这个知识库是干什么用的&#xff0c;只有了解知识库的应用场景才能知道如何去建设知识库。 知识库建设 以常见的电商客服为例&#xff0c;客户会经常咨询什么时候发货&#xff0c;怎么退货&#xff0c;怎么换货………

MySQL——数据库以及数据表的创建

创建数据库 回到刚才创建数据库的问题&#xff0c;我们在创建数据库的时候可以通过添加一个参数&#xff0c;这个参数的意义在于当我们创建的数据库已经存在的时候则不会创建&#xff0c;也不会报错&#xff0c;如果不使用这个参数&#xff0c;则我们在重复创建一个已经存在的…

遥感图像应用:在低分辨率图像上实现洪水损害检测(迁移学习)

本文是上一篇关于“在低分辨率图像上实现洪水损害检测”的博客的延申。 代码来源&#xff1a;https://github.com/weining20000/Flooding-Damage-Detection-from-Post-Hurricane-Satellite-Imagery-Based-on-CNN/tree/master 数据储存地址&#xff1a;https://github.com/Jef…

List常见面试问题

List的特点有哪些&#xff1f; Java中的List是一种存放有序的、可以重复的数据的集合&#xff0c;它允许重复元素的存在。List中的元素都有对应的一个序列号(索引)记录着元素的位置&#xff0c;因此可以通过这个序列号来访问元素。 ‍ Java中集合有哪些&#xff1f; Java中…

便民门诊“快车道”,5G商企专网来护航

时代进步&#xff0c;医疗服务再升级。在贵州铜仁地区&#xff0c;5G诊疗服务尽显温情&#xff0c;“健康守护”走进社区。更便捷高效的就医方式&#xff0c;让百姓尽享“健康红利”。 为搭建就医“快车道”&#xff0c;医院在多地新增设便民门诊&#xff0c;民众就医有了更多的…

misc corrupt

1.打开之后是01二进制 2.利用python二进制转hex或者16进制 print(hex(int(二进制01,2))) 3.利用winHex 4.解码base64

【Java】基础练习(十二)

1.Map基本操作 创建一个Map集合&#xff0c;完成以下操作&#xff1a; 将我国省份和其简称存到 Map 集合中&#xff1b;将省份名称中包含"江"的省份从集合中删除&#xff1b;遍历输出集合元素 &#xff08;1&#xff09;源码&#xff1a; package swp.kaifamiao.c…

学习嵌入式软件工程师面试题(day1)

前言 &#xff08;1&#xff09;如果你在读大学&#xff0c;不管你本科毕业是读研还是就业&#xff0c;你都可以早点准备嵌入式面试题&#xff0c;本系列教程的面试题均基于C语言。 &#xff08;2&#xff09;像嵌入式学得好&#xff0c;且学历不错的本科生和研究生&#xff0c…

应急物资管理系统-完善应急物资保障体系

东识智慧应急物资管理系统&#xff08;智物资DW-S300&#xff09;在政府应急救援物资管理、红十字会应急物资管理、防汛应急物资管理、医疗抗疫物资管理等行业均有成功案例。智物资DW-S300实现了功能一体化管理、流程一体化管理、信息一体化管理&#xff0c;使得资产从采购、入…

循环(while do...while for)介绍

3.循环 1.while循环 while循环是先判断后执行 while循环一般都会有: 循环初始值, 循环条件 和 循环变量增量(或者减量) 语法: while(表达式){逻辑代码块 }// 计算123...100之和var num 1;//循环初始值var sum 0;//统计结果//循环条件while (num < 100) {console.log(n…

Java到底是值传递还是引用传递【通俗易懂】

我相信很多刚学Java的小伙伴都很难理解Java到底是值传递还是引用传递的问题&#xff0c;但肯定背过这道面试题。确实&#xff0c;Java就是值传递&#xff0c;那什么原理呢&#xff1f;请往下看。 我们先看一段代码&#xff1a;分析一下这两句打印的结果分别是什么。 public c…

对象存储 OSS

大家好 , 我是苏麟 , 今天聊聊OSS . 这里使用阿里云的OSS对象存储. 首先大家得有一个阿里云账号 , 注册大家都会 这里不多介绍 . 阿里云官网 : 阿里云登录页 (aliyun.com) 首页产品目录下存储集合里对象存储OSS 进入对象存储OSS页面 点击管理控制台(新用户应该有免费试用期的)…

【数学建模竞赛】预测类赛题常用算法解析

解析常见的预测类算法 灰色预测模型 灰色预测模型是一种利用少量的、不完全的信息&#xff0c;建立数学模型并进行预测的方法。该方法通过对系统行为特征的发展变化规律进行估计预测&#xff0c;同时也可以对行为特征的异常情况发生的时刻进行估计计算&#xff0c;并研究特定…

Python商业数据存取

&#x1f433; 我正在和鲸社区参加“商业数据分析训练营活动” https://www.heywhale.com/home/competition/6487de6649463ee38dbaf58b &#xff0c;以下是我的学习笔记&#xff1a; 学习主题&#xff1a;Python商业数据存取 日期&#xff1a;2023.9.6 关键概念/知识点&…

IMX6ULL移植篇-uboot源码目录表

一. uboot 源码分析前提 由于 uboot 会使用到一些经过编译才会生成的文件&#xff0c;因此&#xff0c;我们在分析 uboot的时候&#xff0c;需要先编译一下 uboot 源码工程。 这里所用的开发板是 nand-flash 版本。 本文学习续上一篇文章&#xff0c;如下&#xff1a; IMX6U…

电商物流解决方案公司Globavend申请纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;电商物流解决方案公司Globavend近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯达克IPO上市&#xff0c;股票代码为&#xff08;GVH&#xff09;&#x…