[leetcode]632. Smallest Range最小范围
You have k lists of sorted integers in ascending order. Find the smallest range that includes at least one number from each of the k lists.
We define the range [a,b] is smaller than range [c,d] if b-a < d-c or a < c if b-a == d-c.
Example 1:
Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
Output: [20,24]
Explanation:
List 1: [4, 10, 15, 24,26], 24 is in range [20,24].
List 2: [0, 9, 12, 20], 20 is in range [20,24].
List 3: [5, 18, 22, 30], 22 is in range [20,24].
Note:
- The given list may contain duplicates, so ascending order means >= here.
- 1 <=
k<= 3500 - -105 <=
value of elements<= 105. - For Java users, please note that the input type has been changed to List<List<Integer>>. And after you reset the code template, you'll see this point.
题意:
给定一些sorted array, 求一个最小范围,使得该范围内至少包含每个数组中的一个数字。
思路:
这个题来自打车公司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的尽头)。
[4,10,15,24,26]
^
zero [0,9,12,20]
^
first [5,18,22,30]
^
second
curMin curMax range pointerIndex
zero|first|second
init 0 5 5 0 | 0 | 0
curMin对应的指针first++ 4 9 5 0 | 1 | 0
curMin对应的指针zero++ 5 10 5 1 | 1 | 0
curMin对应的指针second++ 9 18 9 1 | 1 | 1
curMin对应的指针first++ 10 18 8 1 | 2 | 1
curMin对应的指针zero++ 12 18 6 2 | 2 | 1
curMin对应的指针first++ 15 20 5 2 | 3 | 1
curMin对应的指针zero++ 18 24 6 3 | 3 | 1
curMin对应的指针second++ 20 24 4 3 | 3 | 2
代码一:
public int[] smallestRange2(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)
能够在时间上进行优化。
代码二:
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. Smallest Range最小范围的更多相关文章
- [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 ...
- 【LeetCode】632. Smallest Range 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/smallest ...
- [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 ...
- [LeetCode] 908. Smallest Range I 最小区间
Given an array A of integers, for each integer A[i] we may choose any x with -K <= x <= K, and ...
- 632. Smallest Range(priority_queue)
You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...
- LeetCode 908 Smallest Range I 解题报告
题目要求 Given an array A of integers, for each integer A[i] we may choose any x with -K <= x <= K ...
- LeetCode 910. Smallest Range II
很有意思的一道数学推理题目, 剪枝以后解法也很简洁.初看貌似需要把每个数跟其他数作比较.但排序以后可以发现情况大大简化:对于任一对元素a[i] < a[j], a[i] - k和a[j] + k ...
- [LeetCode] Smallest Range 最小的范围
You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...
- [Swift]LeetCode632. 最小区间 | Smallest Range
You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...
随机推荐
- [UE4]角色、动画蓝图、动画蒙太奇、动画之间的调用关系
一.在“角色”中设置要使用的“动画蓝图” 二.在“动画蓝图”中使用“动画”和“混合动画” 三.在“混合动画”中,也可以使用“动画” 四.在角色中使用“动画蒙太奇”
- [UE4]代理事件(C++)
用宏定义类似格式: DECLARE_DELEGATE //普通代理 DECLARE_DYNAMIC_DELEGATE_TwoParams //动态代理 DECLARE_DYNAMIC_MULTICAS ...
- 用HTML5播放IPCamera视频
HTML5增加了vedio标签,能直接播放视频,但是播放的格式是有限的. 这里将IPCamera的视频转换OGG格式,再通过HTML5网页播放,播放还是很清晰的.IPCamera要支持RTSP等视频流 ...
- 学习URL地址(待整理)
编程开发教程:http://www.runoob.com/ ElasticSearch教程:https://es.xiaoleilu.com/index.html 设计模式:http://www.cn ...
- 第3课 进化后的 const分析
1. C语言中的const (1)const修饰的变量是只读的,使得变量具有只读属性,但本质还是变量.所以不是真正的常量,它只是告诉编译器该变量不能出现在赋值符号的左边. (2)const修饰的局部 ...
- php 数组函数实例
数组的概念 数组(array)是 PHP 中一个非常重要的概念,我们可以把数组看做一系列类似的数据的集合,实际上数组是一个有序图. PHP 还提供了超过 70 个内建函数来操作数组. 由于数组在php ...
- 小朋友学Python(3)
运算符 一.基本运算符 Python运算符多数与C/C++/Java类似,但有少数不一样. “/”表示求商,“//”求商的整数部分.11 / 2 = 5.500000, 11 // 2 = 5 “** ...
- django项目分页
测试版本 代码: # 测试分页users=[{'name':'alex{}'.format(i),'pwd':'aaa{}'.format(i)}for i in range(1,302)] def ...
- django-后台sms管理系统的css框架
地址:https://adminlte.io/ 下载代码.使用index.html的页面及相关文件 通过下在线检查adminlte.io的后台的各种模块元素,仿写.
- JAVA Spring 面向切面编程 基本案例(AOP)
< 1 > 配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&q ...