转:http://www.itmian4.com/thread-6504-1-1.html

最小区间原题

k个有序的数组,找到最小的区间范围使得这k个数组中,每个数组至少有一个数字在这个区间范围内。比如:

  • 数组1:[4, 10, 15, 24, 26]
  • 数组2:[0, 9, 12, 20]
  • 数组3:[5, 18, 22, 30]

最小的区间是[20, 24],这个区间包含了数组1中的24,数组2中的20,数组3中的22

  • 思考时间~~~

分析

该题看起来还算比较简单,大家通常都会想到:为每一个数组设置一个遍历变量,选择最小值的数组,继续往后移动一位。由于是有k个数组,数组的数量有可能很多,所以如何去选择和替换最小的值,我们就会想到一个数据结构最小堆来维护最小的值。

解答方法:
初始化大小为k的最小堆,k个数字是每个数组中的最小值,设置变量maxValue记录k个数字中最大值,删除堆顶元素,将原堆顶元素对应的数组中下一个值加入到堆中,调整堆,并且记录当前区间范围(maxValue - minValue),重复执行直到某个数组所有值都被删除。

比如.
List 1: [4, 10, 15, 24, 26]
List 2: [0, 9, 12, 20]
List 3: [5, 18, 22, 30]

最小堆大小为3. 从三个数组中取最小值
Heap [0, 4, 5] maxValue 5
Range - 6

删除0 ,加入9
Heap [4, 9, 5] maxValue 9
Range - 6

删除4 ,加入10
Heap [5, 9, 10] maxValue 10
Range - 6

重复执行,最终得到结果

代码如下:

 struct pn
{
int n; /* belong to which array */
int d; /* the data value */
pn(int _n, int _d) { n = _n; d = _d; }
pn(const pn& _pn) { n = _pn.n; d = _pn.d; }
}; inline void swap(pn& a, pn& b) { pn c = a; a = b; b = c; } void adjust(int n, pn a[])
{
int i = , max = ;
int l = , r = ;
for(i = n / ; i >= ; i--)
{
max = i;
l = * i + ;
r = * i + ;
if(l < n && a[l].d > a[max].d) { max = l; }
if(r < n && a[r].d > a[max].d) { max = r; }
if(max != i) { swap(a[max], a[i]); }
}
} void heapsort(int n, pn a[])
{
int i = ;
adjust(n, a);
for(i = n - ; i > ; i--)
{
swap(a[], a[i]);
adjust(i, a);
}
} int main()
{
int i = , j = ;
const int m = ;
const int n = ;
int ms = , me = ;
int ts = , te = ;
int a[m][n] = { {, , , , }, {, , , , }, {, , , , } };
int cur[m] = {, , }; /* record the current positions of each array which haven't been used */
pn heap[m] = {pn(, a[][]), pn(, a[][]), pn(, a[][])}; heapsort(m, heap);
ms = heap[].d;
me = heap[m - ].d;
while(true)
{
heapsort(m, heap);
ts = heap[].d;
te = heap[m - ].d;
/* if the current range is smaller than the minimum range */
if(te - ts < me - ms) { ms = ts; me = te; } /* if the sub-array which the smallest element comes from hasn't to the end */
if(cur[heap[].n] != n)
{
heap[].d = a[heap[].n][cur[heap[].n]];
cur[heap[].n] += ;
}
else
{
break;
}
}
cout << ms << endl;
cout << me << endl;
return ;
}

以下是自己的思路:

1 每个数组取最后一个值,从这些值当中选出最小值,记为min。

2 遍历每一个数组(min对应的数组返回-1),从中找到第一个大于min的值,再从这些值当中选出最大值。

3 最小区间即为[min, max]。

不知道有没有漏洞?实现以后补上。

转:最小区间:k个有序的数组,找到最小区间使k个数组中每个数组至少有一个数在区间中的更多相关文章

  1. struts2:遍历自定义字符串数组,遍历Action实例所引用对象中的数组

    在struts2:OGNL表达式,遍历List.Map集合:投影的使用一文中已经讲述了OGNL遍历List.Map集合等功能. 本文简单写一个遍历数组的示范程序. 1. 遍历自定义字符串数组 < ...

  2. 【java】解析java中的数组

    目录结构: contents structure [+] 一维数组 1,什么是一维数组 2,声明一维数组的三种方式 二维数组 1,什么是二维数组 2,声明二维数组的3种方式 3,二维数组的遍历示例 数 ...

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

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

  4. 合并K个有序数组(链表)【字节跳动面试算法题】

    本题是本人字节跳动一面考的算法题原题是有序数组,一时没想到怎么解决数组的问题,但是如果给的是有序链表数组,则可以用下面的方法解决 可以利用最小堆完成,时间复杂度是O(nklogk),具体过程如下: 创 ...

  5. 两个有序数组的中位数(第k大的数)

    问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回上中位数). 感觉这种题目挺难的,尤其是将算法完全写对.因为当初自己微软面试的时候遇到了,但是没有想出来思路. ...

  6. 合并k个有序数组

    给定K个有序数组,每个数组有n个元素,想把这些数组合并成一个有序数组 可以利用最小堆完成,时间复杂度是O(nklogk),具体过程如下: 创建一个大小为n*k的数组保存最后的结果创建一个大小为k的最小 ...

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

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

  8. 合并K个有序数组-Java

    package com.rao.algorithm; import java.util.Arrays; /** * @author Srao * @className MergeK * @date 2 ...

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

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

随机推荐

  1. java环境log4j日志环境的配置。

    首先需要4个jar包.下载地址如下 http://pan.baidu.com/s/1i4k3fiH 期中包含如下包,放到工程的lib中即可.     除此之外还需要一个配置文件,分享链接如下. htt ...

  2. Poj(1797) Dijkstra对松弛条件的变形

    题目链接:http://poj.org/problem?id=1797 题意:从路口1运货到路口n,最大的运货重量是多少?题目给出两路口间的最大载重. 思路:j加到s还是接到K下面,取两者的较大者,而 ...

  3. winform中拖动功能实现技巧

    实现的需求,我通过拖动选中的用户行放到左边的机构节点上,从而实现用户改变组织机构的关系 贴代码 private DataGridViewSelectedRowCollection sourceRowC ...

  4. 2016年10月12日 星期三 --出埃及记 Exodus 18:23

    2016年10月12日 星期三 --出埃及记 Exodus 18:23 If you do this and God so commands, you will be able to stand th ...

  5. SQL与C#结合完整修改 删除信息

    --SQl中--建立ren的数据库,插入一条信息 create database ren go use ren go create table xinxi ( code ) primary key,- ...

  6. 微信网页获取openId

    <%@ WebHandler Language="C#" Class="UserAuth" %> public class UserAuth : I ...

  7. FZU 2168 防守阵地 I

    Problem Description 部队中共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,按重要程度从低到高排序,依次以数字1到M标注每个地点的重要程度, ...

  8. SqlSever基础 dateadd day 增加五天

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  9. js九宫格的碰撞检测

    说来惭愧,我一直以为四四方方的拖拽碰撞检测是一个比较容易的事情,后来试过一次,真是让我耗费了无数的脑细胞,原理其实不难,但是具体做起来可就让我很恶心,这可能跟我驾驭的代码数量有关系,我一般也就写半屏幕 ...

  10. Walkthrough: Arranging Controls on Windows Forms Using Snaplines

    https://msdn.microsoft.com/en-us/library/t5b5kc41(v=vs.110).aspx Spacing and Aligning Controls Using ...