[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 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.
这道题给了我们一些数组,都是排好序的,让求一个最小的范围,使得这个范围内至少会包括每个数组中的一个数字。虽然每个数组都是有序的,但是考虑到他们之间的数字差距可能很大,所以最好还是合并成一个数组统一处理比较好,但是合并成一个大数组还需要保留其原属数组的序号,所以大数组中存pair对,同时保存数字和原数组的序号。然后重新按照数字大小进行排序,这样问题实际上就转换成了求一个最小窗口,使其能够同时包括所有数组中的至少一个数字。这不就变成了那道 Minimum Window Substring。所以说啊,这些题目都是换汤不换药的,总能变成我们见过的类型。这里用两个指针 left 和 right 来确定滑动窗口的范围,还要用一个 HashMap 来建立每个数组与其数组中数字出现的个数之间的映射,变量 cnt 表示当前窗口中的数字覆盖了几个数组,diff 为窗口的大小,让 right 向右滑动,然后判断如果 right 指向的数字所在数组没有被覆盖到,cnt 自增1,然后 HashMap 中对应的数组出现次数自增1,然后循环判断如果 cnt 此时为k(数组的个数)且 left 不大于 right,那么用当前窗口的范围来更新结果,然后此时想缩小窗口,通过将 left 向右移,移动之前需要减小 HashMap 中的映射值,因为去除了数字,如果此时映射值为0了,说明有个数组无法覆盖到了,cnt 就要自减1。这样遍历后就能得到最小的范围了,参见代码如下:
解法一:
class Solution {
public:
vector<int> smallestRange(vector<vector<int>>& nums) {
vector<int> res;
vector<pair<int, int>> v;
unordered_map<int, int> m;
for (int i = ; i < nums.size(); ++i) {
for (int num : nums[i]) {
v.push_back({num, i});
}
}
sort(v.begin(), v.end());
int left = , n = v.size(), k = nums.size(), cnt = , diff = INT_MAX;
for (int right = ; right < n; ++right) {
if (m[v[right].second] == ) ++cnt;
++m[v[right].second];
while (cnt == k && left <= right) {
if (diff > v[right].first - v[left].first) {
diff = v[right].first - v[left].first;
res = {v[left].first, v[right].first};
}
if (--m[v[left].second] == ) --cnt;
++left;
}
}
return res;
}
};
这道题还有一种使用 priority_queue 来做的,优先队列默认情况是最大堆,但是这道题我们需要使用最小堆,重新写一下 comparator 就行了。解题的主要思路很上面的解法很相似,只是具体的数据结构的使用上略有不同,这 curMax 表示当前遇到的最大数字,用一个 idx 数组表示每个 list 中遍历到的位置,然后优先队列里面放一个pair,是数字和其所属list组成的对儿。遍历所有的list,将每个 list 的首元素和该 list 序号组成 pair 放入队列中,然后 idx 数组中每个位置都赋值为1,因为0的位置已经放入队列了,所以指针向后移一个位置,还要更新当前最大值 curMax。此时 queue 中是每个 list 各有一个数字,由于是最小堆,所以最小的数字就在队首,再加上最大值 curMax,就可以初始化结果 res 了。然后进行循环,注意这里循环的条件不是队列不为空,而是当某个 list 的数字遍历完了就结束循环,因为范围要 cover 每个 list 至少一个数字。所以 while 循环条件即是队首数字所在的 list 的遍历位置小于该 list 的总个数,在循环中,取出队首数字所在的 list 序号t,然后将该 list 中下一个位置的数字和该 list 序号t组成 pair,加入队列中,然后用这个数字更新 curMax,同时 idx 中t对应的位置也自增1。现在来更新结果 res,如果结果 res 中两数之差大于 curMax 和队首数字之差,则更新结果 res,参见代码如下:
解法二:
class Solution {
public:
vector<int> smallestRange(vector<vector<int>>& nums) {
int curMax = INT_MIN, n = nums.size();
vector<int> idx(n, );
auto cmp = [](pair<int, int>& a, pair<int, int>& b) {return a.first > b.first;};
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp) > q(cmp);
for (int i = ; i < n; ++i) {
q.push({nums[i][], i});
idx[i] = ;
curMax = max(curMax, nums[i][]);
}
vector<int> res{q.top().first, curMax};
while (idx[q.top().second] < nums[q.top().second].size()) {
int t = q.top().second; q.pop();
q.push({nums[t][idx[t]], t});
curMax = max(curMax, nums[t][idx[t]]);
++idx[t];
if (res[] - res[] > curMax - q.top().first) {
res = {q.top().first, curMax};
}
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/632
类似题目:
参考资料:
https://leetcode.com/problems/smallest-range-covering-elements-from-k-lists/
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 632. Smallest Range Covering Elements from K Lists 覆盖K个列表元素的最小区间的更多相关文章
- [leetcode]632. Smallest Range最小范围
You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...
- 求包含每个有序数组(共k个)至少一个元素的最小区间
title: 求包含每个有序数组(共k个)至少一个元素的最小区间 toc: false date: 2018-09-22 21:03:22 categories: OJ tags: 归并 给定k个有序 ...
- 【LeetCode】632. Smallest Range 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/smallest ...
- 632. Smallest Range(priority_queue)
You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...
- [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 ...
- LeetCode 910. Smallest Range II
很有意思的一道数学推理题目, 剪枝以后解法也很简洁.初看貌似需要把每个数跟其他数作比较.但排序以后可以发现情况大大简化:对于任一对元素a[i] < a[j], a[i] - k和a[j] + k ...
- 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] Smallest Range 最小的范围
You have k lists of sorted integers in ascending order. Find the smallest range that includes at lea ...
随机推荐
- python中pkl用法
原文连接:https://www.jianshu.com/p/2ecadebe6d13 python中pkl用法 经常遇到在Python程序运行得到了一些字符串.列表.字典等数据,想要长久的保存下来, ...
- rpc和webservice的关系简述
RPC(Remote Procedure Call,远程过程调用)是一个很大的概念.它是一种通过网络从远程计算机程序上跨语言跨平台的请求服务.RPC能省略部分接口代码的开发,可以跨机器之间访问对象(J ...
- 专栏《Elasticsearch 7.x从入门到精通》的相关源代码
新版Elasticsearch 7.3 和 Spring Boot 2.1.7 集成演示项目 第一个项目:演示Elasticsearch 6.4.3 和Spring Boot 2.1.7集 ...
- Elasticsearch PUT 插入数据
{ "error": { "root_cause": [ { "type": "illegal_argument_exceptio ...
- 大话区块链【Blockchain】
最近这几天区块链又粉墨登场了,新闻媒体也一直在大量报道,宣称可能要在金融界掀起一番浪潮.甚至有人说很久之前中国就出现了区块链的产物——麻将.那么区块链到底是什么,麻将和区块链又有什么关系呢? 笔者这两 ...
- Microsoft.Office.Interop.Excel 读取 excel 中的 checkbox 和 radio
using Excel = Microsoft.Office.Interop.Excel; Excel.Application excelapp = new Excel.Application(); ...
- 关于git回退版本的一点心得
我由于开发中不小心在master分支上开发,忘记了切换分支,最后我直接在master分支上提交,push,在开发分支上merge了master分支. 然后,同事告诉我他的代码要准备上线了,然而我的代码 ...
- 让你的项目使用Ts吧
推荐在这里阅读 9012年都过半了,还不会用ts你就out了 why ? 三大框架angular2以后的版本完全是用ts开发的, vue对ts的支持也越来越好, React也有TSX组件 还在犹豫什么 ...
- Java基础回顾——反射+案例
一,引言: 从大二刚开始接触java,了解其基本语法,到用swing编写图形界面的程序,到JavaWeb用SSH三大框架编写小网站,后面又学SSM,SpringBoot,SpringCloud等.可以 ...
- APS系统生产流转方式和批量算法研究
01.前言 在经济领域,生产型企业是经济的根基,有了生产型企业生产出的各种产品,才有物流.网上购物和金融融资等活动.对于生产型企业,其制造能力是其核心竞争力.如何提升制造能力一直是生产型企业面临的课题 ...