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

toc: false

date: 2018-09-22 21:03:22

categories:

  • OJ

tags:

  • 归并

给定k个有序数组, 每个数组有个N个元素,找出一个最小的闭区间,使其包含每个数组中的至少一个元素。

关于最小区间——

给定两个区间[a,b], [c,d]:

如果 b-a < d-c,则认为[a, b]是更小的区间;

如果 b-a == d-c,且a < c,则认为[a, b]是更小的区间。

不妨设k为3,分别为a,b,c数组且a1<=b1<=c1,当前最小区间长度为INT_MAX

假设三个数组所有元素排序后为:

a1,...,b1,...,c1,.....

我们考虑最小的a1,若最小区间包含的a数组的元素为a1,则若[a1,c1]的长度小于当前最小区间长度,更新最小区间长度为c1-a1,

然后我们丢弃a1,因为若最小区间包含的a数组元素为a1,则最小区间一定为[a1,c1],而我们已经更新了这个长度;若不是a1,则丢弃a1也无关紧要,不影响最后结果。

那么现在我们一直的最小区间长度为c1-a1,三个数组剩下所有元素排序后可能为

a2,..,b1,..,c1,...或

b1,..,a2,..c1,...或

b1,..,c1,..a2...

第一种情况就类似于上边讨论的情况,更新最小区间长度为c1-a2,然后丢弃a2。

对于后两种情况,我们考虑最小的b1:

若最小区间包含的b数组的元素为b1,则最小区间包含的一定为b1,c1,a2,我们更新最小区间长度,然后丢弃b1,

若不是b1,则丢弃b1;

这样不断循环地考虑最小值,直到丢弃完了某一个数组的所有值,这样我们的当前最小区间长度就是所求结果。

下边是代码:

#include <iostream>
#include <limits.h>
#include <vector>
using namespace std; int main() {
int k, n;
cin>>k>>n;
if (k <= 0 || n <= 0) return 0;
vector<vector<int> > nums;
vector<int> pos;
for (int i = 0; i < k; i++) {
vector<int> arrayI;
int tmp;
for (int j = 0; j < n; j++) {
cin>>tmp;
arrayI.push_back(tmp);
}
nums.push_back(arrayI);
pos.push_back(0);
}
int minLength = INT_MAX;
int realMin, realMax;
while (true) {
int arrayOfLeastNum = -1;
int tmpMin = INT_MAX;
int tmpMax = INT_MIN;
for (int i = 0; i < k; i++) {
if (nums[i][pos[i]] < tmpMin) {
tmpMin = nums[i][pos[i]];
arrayOfLeastNum = i;
}
if (nums[i][pos[i]] > tmpMax) {
tmpMax = nums[i][pos[i]];
}
}
if (tmpMax - tmpMin < minLength) {
minLength = tmpMax - tmpMin;
realMin = tmpMin, realMax = tmpMax;
}
if (++pos[arrayOfLeastNum] >= n) break;
}
cout<<realMin<<' '<<realMax;
return 0;
}

但是,这个只能过90%:

运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。

case通过率为90.00%

看了一下题下的讨论,可以用一个优先队列(priority_queue,一个STL)或自己实现一个最小堆来维护“当前最小区间队列”,这样查找当前的最大值和最小值就是O(logn)而不是O(n)

下边帖一下别人的代码:

链接:https://www.nowcoder.com/questionTerminal/0399d363fb594970bae7ad8a3978f86a
来源:牛客网 //思路2,用优先队列去实现多路归并 #include<bits/stdc++.h>
using namespace std;
struct pt{
int x;
int pos;
pt(int a,int b):x(a),pos(b){}
};
struct cmp{ //重写比较函数
bool operator()(const pt a,const pt b){
return a.x>b.x;
}
};
int main(){
int k,n;
while(cin>>k>>n){
vector<vector<pt>>all;
vector<int> vec;
for(int i = 0;i<k;i++){
vector<pt>temp;
for(int j = 0;j<n;j++){
int x;
cin>>x;
pt p(x,i);
temp.push_back(p);
}
all.push_back(temp);
vec.push_back(0);
}
vector<pt> sort;
priority_queue<pt,vector<pt>,cmp> qu; //优先队列
for(int i = 0;i<k;i++)
qu.push(all[i][0]);
while(!qu.empty()){
pt temp = qu.top();
qu.pop();
sort.push_back(temp);
vec[temp.pos]++;
if(vec[temp.pos]<=n-1){
qu.push(all[temp.pos][vec[temp.pos]]);
}
}
for(int i = 0;i<vec.size();i++)
vec[i] = 0;
int begin = 0;
int end = 0;
int start = 0;
int final = 0;
int length = INT_MAX;
bool flg = false;
vec[sort[0].pos]++;
while(begin<sort.size()-1||end<sort.size()-1){
bool flgg = true;
for(int i = 0;i<k;i++)
flgg = flgg&&(vec[i]>=1);
if(!flgg&&end<sort.size()){
if(end<sort.size()-1)
end++;
vec[sort[end].pos]++;
}
if(!flgg&&end==sort.size()-1)
break;
if(flgg&&begin<sort.size()){
int x = sort[end].x-sort[begin].x;
if(x<length){
start = sort[begin].x;
final = sort[end].x;
length = x;
}
vec[sort[begin].pos]--;
if(begin<sort.size()-1)
begin++;
}
int a = 1;
}
cout<<start<<" "<<final<<endl;
}
system("pause");
return 0;
}

求包含每个有序数组(共k个)至少一个元素的最小区间的更多相关文章

  1. 求两个有序数组的中位数或者第k小元素

    问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回上中位数). 设两个数组分别是vec1和vec2,元素数目分别是n1.n2. 算法1:最简单的办法就是把两个数 ...

  2. Codeforces Round #283 (Div. 2) A. Minimum Difficulty【一个数组定义困难值是两个相邻元素之间差的最大值。 给一个数组,可以去掉任意一个元素,问剩余数列的困难值的最小值是多少】

    A. Minimum Difficulty time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  3. 【递归打卡2】求两个有序数组的第K小数

    [题目] 给定两个有序数组arr1和arr2,已知两个数组的长度分别为 m1 和 m2,求两个数组中的第 K 小数.要求时间复杂度O(log(m1 + m2)). [举例] 例如 arr1 = [1, ...

  4. 求两个有序数组的中位数(4. Median of Two Sorted Arrays)

    先吐槽一下,我好气啊,想了很久硬是没有做出来,题目要求的时间复杂度为O(log(m+n)),我猜到了要用二分法,但是没有想到点子上去.然后上网搜了一下答案,感觉好有罪恶感. 题目原型 正确的思路是:把 ...

  5. [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 ...

  6. JS数组at函数(获取最后一个元素的方法)介绍

    本文介绍js中数组的at函数,属于比较简单的知识普及性文章,难度不大. 0x00 首先,我们可以思考如下一个问题,如果要获取一个数组的最后一个元素(这是很常用的操作),我们应该怎么做? 相信大部分人能 ...

  7. 算法-求两个有序数组两两相加的值最小的K个数

    我的思路是: 用队列,  从(0,0)開始入队,每次出队的时候,选(1,0) (0,1) 之间最小的入队,假设是相等的都入队,假设入过队的就不入了,把出队的k个不同的输出来就可以 我測试了几组数据都是 ...

  8. Median of Two Sorted 求两个有序数组的中位数

    中位数是把一个数的集合划分为两部分,每部分包含的数字个数相同,并且一个集合中的元素均大于另一个集合中的元素. 因此,我们考虑在一个任意的位置,将数组A划分成两部分.i表示划分数组A的位置,如果数组A包 ...

  9. 给定一个值S,在有序数组中找出两个元素A和B,使 A+B = S.

    在网上看到过一个面试题,感觉挺有意思,看别人的代码写的逻辑不够谨慎,重写了一个,较真了又... package com.array7.algorithm; public class Algorithm ...

随机推荐

  1. 多线程之HttpClient

    在程序用调用 Http 接口.请求 http 资源.编写 http 爬虫等的时候都需要在程序集中进行 Http 请求. 很多人习惯的 WebClient.HttpWebRequest 在 TPL 下很 ...

  2. java exception 异常错误记录

    //异常:Could not obtain transaction-synchronized Session for current thread 做定时器的时候用ApplicationContext ...

  3. LeetCode 75. Sort Colors (python一次遍历,模拟三路快排)

    LeetCode 75. Sort Colors (python一次遍历,模拟三路快排) 题目分析: 本题需要实现数字只包含0,1,2的排序,并且要求一次遍历. 由于只用把数字隔离开,很容易想到快排的 ...

  4. hdu3938 Portal 离线的并查集

    离线算法是将全部输入都读入,计算出所有的答案以后再输出的方法.主要是为避免重复计算.类似于计算斐波那契数列的时候用打表的方法. 题目:给一个无向图,求有多少个点对,使得两点间的路径上的花费小于L,这里 ...

  5. JavaEE学习记录

    软件152谭智馗 一.JavaEE开发环境配置 1.准备以下压缩包 (1)JDK1.7:jdk1.7.rar (2)开发工具:eclipse-jee-mars-2 (3)项目管理工具:maven-3. ...

  6. 【Oracle】DBA_AUDIT_TRAIL表SES_ACTIONS字段对应的操作列表

    SES_ACTIONS字段共包含16个字符,初始状态都为“-”,当被审计的对象被操作后,SES_ACTIONS会在相应的位置作出标识,标识为“S”的代表操作成功,标识为“F”的代表操作失败,16个位置 ...

  7. SIFT算法总结:用于图像搜索

    原始文章链接:http://bubblexc.com/y2011/163/ 原文链接:http://blog.csdn.net/cserchen/article/details/5606859 关于三 ...

  8. C++目录遍历:使用第三方库boost.filesystem等

    1. opencv 目录文件遍历 注释:2014 0814 这个代码是基于java的,Java使用托管代码进行目录管理,C++就不那么跨平台了. 原文链接:http://blog.csdn.net/z ...

  9. 01--vim常用快捷键

    Linux中vim编辑器的功能非常强大,许多常用快捷键用起来非常方便,这里将我学vim入门时学的一些常用的快捷键分享给大家一下,希望可以帮助你们.   这个是我将鸟哥书上的进行了一下整理的,希望不要涉 ...

  10. RabbitMQ学习之基于spring-rabbitmq的RPC远程调用

    http://blog.csdn.net/zhu_tianwei/article/details/40920985 spring-rabbitmq中实现远程接口调用,主要在com.rabbitmq.s ...