最小区间

你有 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. 给定的列表可能包含重复元素,所以在这里升序表示 >= 。
  2. 1 <= k <= 3500
  3. -105 <= 元素的值 <= 105
  4. 对于使用Java的用户,请注意传入类型已修改为List<List<Integer>>。重置代码模板后可以看到这项改动。

思路

这个题来自打车公司lyft,现实意义是模拟该app在很多user登陆的登陆时间,narrow一个范围,这样就可以在user登陆时间最频繁的范围里投放广告或者做些其他的商业行为。

two pointer的思路。

三个指针zero、first、second同时从每个list的首元素出发。用pointerIndex来维护一个数组记录每个list当前指针的index。

比较三个指针对应的元素大小。记录比较后的curMin, curMax,更新smallest range。

移动curMin对应的指针,比较三个指针对应的元素大小。记录比较后的curMin, curMax,更新smallest range。 更新pointerIndex。

直至curMin对应的指针无法移动为止(即curMin走到了某个list的尽头)。

 class Solution {
public int[] smallestRange(List<List<Integer>> nums) {
int curMin = 0;
int curMax = Integer.MAX_VALUE;
int[] pointerIndex = new int[nums.size()];// maintain一个数组来记录每层list当前的pointer的index
boolean flag = true; // flag辅助判断是否有某个list走到了末尾 for (int i = 0; i < nums.size() && flag; i++) { // 外层循环遍历list
for (int j = 0; j < nums.get(i).size() && flag; j++) { // 内层循环遍历某个list的第 j 个元素
int minValueLevel = 0;
int maxValueLevel = 0;
for (int k = 0; k < nums.size(); k++) {
if (nums.get(minValueLevel).get(pointerIndex[minValueLevel]) > nums.get(k).get(pointerIndex[k])) {
minValueLevel = k;
}
if (nums.get(maxValueLevel).get(pointerIndex[maxValueLevel]) < nums.get(k).get(pointerIndex[k])) {
maxValueLevel = k;
}
}
// 是否更新smallest range
if (nums.get(maxValueLevel).get(pointerIndex[maxValueLevel]) - nums.get(minValueLevel).get(pointerIndex[minValueLevel]) < curMax - curMin) {
curMin = nums.get(minValueLevel).get(pointerIndex[minValueLevel]);
curMax = nums.get(maxValueLevel).get(pointerIndex[maxValueLevel]);
}
// 移动当前找到的最小值对应的pointer
pointerIndex[minValueLevel]++;
// flag辅助判断是否有某个list走到了末尾
if (pointerIndex[minValueLevel] == nums.get(minValueLevel).size()) {
flag = false;
break;
} }
}
return new int[]{curMin, curMax};
}
}

这个代码在oj上显示time limit exceeded

因为每次都要比较三个指针对应元素的curMin和curMax,  我们可以用一个PriorityQueue来优化。

PriorityQueue里面存放当前三个指针对应的元素。

PriorityQueue 删除极值的时间复杂度是 O(logN), 查找极值的时间复杂度是 O(1)

能够在时间上进行优化。

这个代码在oj上显示time limit exceeded

因为每次都要比较三个指针对应元素的curMin和curMax,  我们可以用一个PriorityQueue来优化。

PriorityQueue里面存放当前三个指针对应的元素。

PriorityQueue 删除极值的时间复杂度是 O(logN), 查找极值的时间复杂度是 O(1)

能够在时间上进行优化。

 import java.util.List;
import java.util.PriorityQueue; class Solution {
public int[] smallestRange(List<List<Integer>> nums) {
int curMin = 0;
int curMax = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
int[] pointerIndex = new int[nums.size()];
boolean flag = true;
PriorityQueue<Integer> queue = new PriorityQueue<Integer>((i, j) -> nums.get(i).get(pointerIndex[i]) - nums.get(j).get(pointerIndex[j]));
for (int i = 0; i < nums.size(); i++) {
queue.add(i);
max = Math.max(max, nums.get(i).get(0));
}
for (int i = 0; i < nums.size() && flag; i++) {
for (int j = 0; j < nums.get(i).size() && flag; j++) {
int minValueLevel = queue.poll();
// 是否更新smallest range
if (max - nums.get(minValueLevel).get(pointerIndex[minValueLevel]) < curMax - curMin) {
curMin = nums.get(minValueLevel).get(pointerIndex[minValueLevel]);
curMax = max;
}
// 移动当前找到的最小值对应的pointer
pointerIndex[minValueLevel]++;
// flag辅助判断是否有某个list走到了末尾
if (pointerIndex[minValueLevel] == nums.get(minValueLevel).size()) {
flag = false;
break;
}
queue.offer(minValueLevel);
max = Math.max(max, nums.get(minValueLevel).get(pointerIndex[minValueLevel])); }
}
return new int[]{curMin, curMax};
}
}

Leetcode 632.最小区间的更多相关文章

  1. Java实现 LeetCode 632 最小区间(又是先序队列,官方给的是堆)

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

  2. [Swift]LeetCode632. 最小区间 | Smallest Range

    You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...

  3. 转:最小区间:k个有序的数组,找到最小区间使k个数组中每个数组至少有一个数在区间中

    转:http://www.itmian4.com/thread-6504-1-1.html 最小区间原题 k个有序的数组,找到最小的区间范围使得这k个数组中,每个数组至少有一个数字在这个区间范围内.比 ...

  4. LeetCode:汇总区间【228】

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

  5. 求包含每个有序数组(共k个)至少一个元素的最小区间

    title: 求包含每个有序数组(共k个)至少一个元素的最小区间 toc: false date: 2018-09-22 21:03:22 categories: OJ tags: 归并 给定k个有序 ...

  6. leetcode 64. 最小路径和 动态规划系列

    目录 1. leetcode 64. 最小路径和 1.1. 暴力 1.2. 二维动态规划 2. 完整代码及执行结果 2.1. 执行结果 1. leetcode 64. 最小路径和 给定一个包含非负整数 ...

  7. B. Uniqueness 删除最小区间内的元素使得剩余元素唯一

    B. Uniqueness time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  8. [LeetCode] 632. Smallest Range Covering Elements from K Lists 覆盖K个列表元素的最小区间

    You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...

  9. [LeetCode] 910. Smallest Range II 最小区间之二

    Given an array A of integers, for each integer A[i] we need to choose either x = -K or x = K, and ad ...

随机推荐

  1. 您H1B身份的申请或H1B延期的申请提交对地方了吗?

    由于H1B配额的短缺,任何关于移民局对H1B申请的改动对马上要申请H1B的外国学生或专业人士来说都很重要.美国移民局在2007年3月5号发布了关于更改接收H1B身份申请或H1B延期申请的新政策. 申请 ...

  2. happy2018暑期集训课后习题001

    根据需求补全下面的代码: 需求: 每行输入三个整数a.b.c,根据a的值不同对b和c进行不同的操作: a为0时,计算b+c a为1时,计算b-c a为2时,计算b*c a为3时,计算b/c 并输出操作 ...

  3. IOS 响应者链条 and UIGestureRecognizer 手势识别器)

    一次完整的触摸事件的传递响应的过程 UIAppliction --> UIWiondw -->递归找到最适合处理事件的控件 控件调用touches方法-->判断是否实现touches ...

  4. Spark运行命令示例

    local单机模式:结果xshell可见:./bin/spark-submit --class org.apache.spark.examples.SparkPi --master local[1] ...

  5. angular路由学习笔记

    文章目录 标签routerLink路由传递参数 url中get传值 定义路由 获取参数 配置动态路由 定义路由 获取参数 API js路由跳转 配置动态路由 定义路由 获取参数 get传值 定义路由 ...

  6. z-index、absolute、marquee滚动条的问题

    1.z-index 层次叠加 ,元素叠加,谁的权重大谁就在上面 1).父级出现position:relation:的时候,失效: 2).层叠元素出现float的时候失效: 3).层次元素也得设置pos ...

  7. 织梦dedecms出现系统基本参数空白或显示Call to undefined function make_hash()

    织梦dedecms出现系统基本参数空白或显示Call to undefined function make_hash() 最新的织梦版本(2018-01-09)修改了include文件夹中的commo ...

  8. C++的XML编程经验――LIBXML2库使用指南

    C++的XML编程经验――LIBXML2库使用指南 写这篇文章的原因有如下几点:1)C++标准库中没有操作XML的方法,用C++操作XML文件必须熟悉一种函数库,LIBXML2是其中一种很优秀的XML ...

  9. SQL Server数据库日志清除

    第一步 将数据库转换成 simple 模式 USE master GO ALTER DATABASE 所要删除日志的数据库名 SET RECOVERY SIMPLE WITH NO_WAIT GO 第 ...

  10. Docker学习笔记--2 镜像的创建

    如果我们需要在Docker环境下部署tomcat.redis.mysql.nginx.php等应用服务环境,有下面三种方法: 1,根据系统镜像创建Docker容器,这时容器就相当于是一个虚拟机,进入容 ...