转: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. jar的下载地址及其使用说明

    有时候会苦于jar的搜索.这里我就给出我平时用到的吧,方便大家.后期会不断添加. 1.dom4j-1.6.1.jar 主要用于解析xml的jar包.下载地址:   http://pan.baidu.c ...

  2. js查找出现次数最多的字母

    <!doctype html><html><head><meta charset="utf-8"><title>无标题文 ...

  3. GROUP BY和ORDER BY共用

    SELECT BatchNumber,MAX(Id) FROM dbo.SceneryOrder AND BatchNumber<>'' GROUP BY BatchNumber DESC

  4. Android任务和返回栈完全解析

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/41087993 本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工 ...

  5. 编译android源码官方教程(4)开始编译

    Preparing to Build IN THIS DOCUMENT Obtain proprietary binaries Download proprietary binaries Extrac ...

  6. zImage.img、ramdisk.img、system.img、userdata.img介绍及解包、打包方法

    ramdisk.img system.img userdata.img介绍及解包.打包方法 Android 源码编译后,在out/target/product/generic下生成ramdisk.im ...

  7. STM32 NVIC

    在stm32中是要配置nvic的.何为nvic,对于我这样的初学者来说,直观感受就是在设置为中断后 还需要配置 中断的优先级nvic就是搞这个的. 那么具体的需要配置些什么那? void NVIC_C ...

  8. map的使用(自增)ret = map(lambda x : x+100 if x % 2 == 1 else x - 100, [1,2,3,4,5])

    #!/usr/bin/env python ret = map(lambda x : x+100 if x % 2 == 1 else x - 100, [1,2,3,4,5]) print(ret) ...

  9. c++ float 带 e 的指数

    带e是指10的 e后面次方 #include <iostream> int main() { float f; f = 9.87654321f; std::cout << f ...

  10. C#获取百度新歌TOP50

    先上软件效果图 代码如下1.根据Url地址得到网页的html源码 public static string GetWebContent(string Url) { string strResult = ...