632. 最小区间

你有 k 个升序排列的整数数组。找到一个最小区间,使得 k 个列表中的每个列表至少有一个数包含在其中。

我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < c,则区间 [a,b] 比 [c,d] 小。

示例 1:

输入:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]

输出: [20,24]

解释:

列表 1:[4, 10, 15, 24, 26],24 在区间 [20,24] 中。

列表 2:[0, 9, 12, 20],20 在区间 [20,24] 中。

列表 3:[5, 18, 22, 30],22 在区间 [20,24] 中。

注意:

给定的列表可能包含重复元素,所以在这里升序表示 >= 。

1 <= k <= 3500

-105 <= 元素的值 <= 105

对于使用Java的用户,请注意传入类型已修改为List<List>。重置代码模板后可以看到这项改动。

class Solution {
public int[] smallestRange(List<List<Integer>> nums) {
if(nums == null || nums.size() == 0)
return null;
int len = nums.size();
PriorityQueue<Pair> queue = new PriorityQueue<>(Comparator.comparingInt(p -> p.num));
int[] res = new int[2];
res[1] = Integer.MAX_VALUE;
//maxNum 记录每一次遍历中k个数组的最大值
int maxNum = Integer.MIN_VALUE;
//初始化优先队列,将k个数组的第一个数字入队
for(int i = 0;i<len;i++){
int num = nums.get(i).get(0);
maxNum = Math.max(maxNum,num);
queue.add(new Pair(i,0,num));
}
//这里的循环退出条件是队列为空,也可以写成双层循环遍历数组
while(!queue.isEmpty()){
//每次遍历,先从队列中取出当前最小值
Pair pair = queue.poll();
int num = pair.num;
//如果(当前最小值,当前最大值)的区间范围更小,则修改res数组
if(res[1] - res[0] > maxNum - num){
res[0] = num;
res[1] = maxNum;
}
int row = pair.row;
//右移
int col = pair.col + 1;
//如果右移后超出数组长度,此时退出循环,即已经找到最小的区间了
if(nums.get(row).size() == col){
break;
}
//下一个数,是当前数右边的数
int nextNum = nums.get(row).get(col);
//下一个数继续入队列
queue.add(new Pair(row,col,nextNum));
//更新当前最大值
maxNum = Math.max(maxNum,nextNum);
}
return res;
}
//定义一个类,用来记录遍历过程中,每个数字所在的行、列和数字对应的值
class Pair{
public Integer row;
public Integer col;
public Integer num;
public Pair(Integer row,Integer col,Integer num){
this.row = row;
this.col = col;
this.num = num;
}
}
}

官方的解法

class Solution {
public int[] smallestRange(List<List<Integer>> nums) {
int minx = 0, miny = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
int[] next = new int[nums.size()];
boolean flag = true;
// 最小堆维护的是当前的最小值,在哪个列表中。注意该堆的比较器。
PriorityQueue<Integer> min_queue = new PriorityQueue<Integer>((i,j) -> nums.get(i).get(next[i])-nums.get(j).get(next[j]));
// 初始化堆
for(int i=0;i<nums.size();i++){
min_queue.offer(i);
max = Math.max(max,nums.get(i).get(0));
}
// 从堆中取得当前最小元素所在的列表。根据next[i],取得其所在位置,多路指针法,类似于丑数;
// 经前面分期,第二个列表就是min_i在其列表的后一位及其之前其他数字组成的区间。最小值由最小堆(决定min_i)及next[min_i]维护,
// 最大值由max = Math.max(max, nums.get(min_i).get(next[min_i]))维护。 for(int i=0;i<nums.size()&&flag;i++){
for(int j=0;j<nums.get(i).size()&&flag;j++){
int min_i = min_queue.poll();
// 选择更小的区间
if(miny-minx> max - nums.get(min_i).get(next[min_i])){
miny = max;
minx = nums.get(min_i).get(next[min_i]);
}
// 由于next改变,min_i加入堆后,堆结构也会改变
next[min_i]++;
if(next[min_i]>=nums.get(min_i).size()){
flag = false;
break;
}
min_queue.offer(min_i);
max = Math.max(max, nums.get(min_i).get(next[min_i]));
}
}
return new int[]{minx,miny};
}
}

Java实现 LeetCode 632 最小区间(又是先序队列,官方给的是堆)的更多相关文章

  1. Leetcode 632.最小区间

    最小区间 你有 k 个升序排列的整数数组.找到一个最小区间,使得 k 个列表中的每个列表至少有一个数包含在其中. 我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < ...

  2. Java实现 LeetCode 539 最小时间差(单位转换)

    539. 最小时间差 给定一个 24 小时制(小时:分钟)的时间列表,找出列表中任意两个时间的最小时间差并已分钟数表示. 示例 1: 输入: ["23:59","00:0 ...

  3. Java实现 LeetCode 453 最小移动次数使数组元素相等

    453. 最小移动次数使数组元素相等 给定一个长度为 n 的非空整数数组,找到让数组所有元素相等的最小移动次数.每次移动可以使 n - 1 个元素增加 1. 示例: 输入: [1,2,3] 输出: 3 ...

  4. Java实现 LeetCode 310 最小高度树

    310. 最小高度树 对于一个具有树特征的无向图,我们可选择任何一个节点作为根.图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树.给出这样的一个图,写出一个函数找到所有的最小高度树 ...

  5. Java实现 LeetCode 228 汇总区间

    228. 汇总区间 给定一个无重复元素的有序整数数组,返回数组区间范围的汇总. 示例 1: 输入: [0,1,2,4,5,7] 输出: ["0->2","4-> ...

  6. Java实现 LeetCode 155 最小栈

    155. 最小栈 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈. push(x) – 将元素 x 推入栈中. pop() – 删除栈顶的元素. top() – 获取 ...

  7. Java实现 LeetCode 64 最小路径和

    64. 最小路径和 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [ [1,3,1], ...

  8. Java实现 LeetCode 57 插入区间

    57. 插入区间 给出一个无重叠的 ,按照区间起始端点排序的区间列表. 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间). 示例 1: 输入: inte ...

  9. Java实现 LeetCode 56 合并区间

    56. 合并区间 给出一个区间的集合,请合并所有重叠的区间. 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: ...

随机推荐

  1. .Net Core微服务化ABP之六——处理Authentication

    上篇中我们已经可以实现sso,并且为各个服务集成sso认证.本篇处理权限系统的角色问题,权限系统分两层,第一层为整体系统角色权限,区分app用户.后台用户.网站用户的接口权限,第二层为业务系统权限,对 ...

  2. HTTP Strict Transport Security (通常简称为HSTS)

    HTTP Strict Transport Security (通常简称为HSTS) 是一个安全功能,它告诉浏览器只能通过HTTPS访问当前资源, 禁止HTTP方式. Freebuf百科:什么是Str ...

  3. Mockito如何mock一条链式调用

    在写单元测试的时候,不免可能需要mock一些对象出来,并且mock一些方法调用去返回一个自己想要的对象.一般的使用是这样的: FinalPumpkin pumpkin = mock(FinalPump ...

  4. 如何搭建一个WEB服务器项目(五)—— Controller返回JSON字符串

    从服务器获取所需数据(JSON格式) 观前提示:本系列文章有关服务器以及后端程序这些概念,我写的全是自己的理解,并不一定正确,希望不要误人子弟.欢迎各位大佬来评论区提出问题或者是指出错误,分享宝贵经验 ...

  5. React实践:自定义html特性不显示

    发现React中自定义的html特性在render后是不现实,而且getAttribute方法也只能获取到undefined. 后来去stackoverflow提问,网友回答说: It depends ...

  6. pyhton中的深浅copy

    深浅拷贝:数据分离情况 1. =赋值:数据完全共享(指向内存中的同一个对象)被赋值的变量指向的数据和原变量的数据都是指向内存中的同一个地址: (1)如果是不可变数据类型(数字.字符串等),修改其中的一 ...

  7. Jenkins-插件开发(简单demo)

    推荐:官网创建插件案例:https://jenkins.io/doc/developer/tutorial/run/ 官方的这篇文章讲的很详细了,我就补充补充其中遇到的一些问题. 前置条件:maven ...

  8. asp.net MVC3.0 中@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction

    asp.net MVC3.0 中@Html.Partial,@Html.Action,@Html.RenderPartial,@Html.RenderAction 1.带有Render的方法返回值是v ...

  9. logger日志接口SLF4J

    SLF4J只是一个接口,可以实现程序的解藕.SLF4J可以与log4j.logback.jdk等日志系统结合,以及在这些日志系统之间切换. 使用maven导入各个日志系统的jar包.需要注意的是要写相 ...

  10. 从无到有Springboot整合Spring-data-jpa实现简单应用

    本文介绍Springboot整合Spring-data-jpa实现简单应用 Spring-data-jpa是什么?这不由得我们思考一番,其实通俗来说Spring-data-jpa默认使用hiberna ...