求k个数组包含每个数组至少一个元素的最小范围(待字闺中,备忘)

2023-10-30

有k个有序的数组,请找到一个最小的数字范围。使得这k个有序数组中,每个数组都至少有一个数字在该范围中。

例如:


1: 4, 10, 15, 24, 26

2: 0, 9, 12, 20

3: 5, 18, 22, 30


所得最小范围为[20,24],其中,20在2中,22在3中,24在1中。


这是待字闺中的一道面试题,就个人经验来看一般有序数组的题目都会让人联想到有折半查找来解决,到有序数组为多个时,一般会联想到归并排序的思想,那么这道题就不例外。


以下引自待字闺中的分析:

那这个题目选择哪个方法继续尝试呢?那我们再分析一下要解决的问题。找到一个最小的范围,每一个有序数组中,都至少有一个元素在这个范围中。找到这样一个范围并不难,可是如何确定最小的范围呢?最终得到的最小的范围,至少包含三个元素,并且在所有数组整体的排序中,是相邻的。假设最小范围是[a, b, c],a < b < c。 c-a是最小的。并且,a,b,c来自不同的有序数组。还有一种情况是[a,b,d,c],a,b,c不是紧邻的,中间有一个d即: a< d < c。这时,d只能是来自b所在的数组,如下分析:

  1. d来自a所在的数组,那么应有更短的范围c - d

  2. d来自c所在的数组,那么应有更短的范围d - a

  3. d来自b所在的数组,范围大小是不变的,就是无论是考虑d,还是考虑b。都没有影响。

从上面的分析,我们得出,只需要考虑在最终的排序中,考虑邻近的、并且来自不同有序数组的元素,作为备选的范围。那么该怎么样做到只考虑临近的、并且来自不同的有序数组的元素呢?这里就用到了归并排序的思想。以原题中的例子为例,假设有三个指针指,p1,p2,p3,分别指向三个数组的第一个元素:

步骤 指针当前值 最大值 最小值 min_range_value 移动指针
1 4,0,5 5 0 5 p2
2 4,9,5 9 4 5 p1
3 10,9,5 10 5 5 p3
4 10,9,18 18 9 9 p2
5 10,12,18 18 10 8 p1
6 15,12,18 18 12 6 p2
7 15,20,18 20 15 5 p1
8 24,20,18 24 18 6 p3
9 24,20,22 24 20 4 p2
end

结束是因为第二个数组已经没有元素可以再进行遍历了。最终得到最小的min_range_value为4,即为题目例子的答案。

上面这个方法,通过归并排序的思想,确保每次都是k个来自不同的数组的元素进行比较,得到最大值、最小值。就可以得到一个范围,包含了所有数组中的数字。

这个题的著名变种是从网页中产生包含所有查询词的最小的摘要。如果你 面过Google,你应该听说过这题。

个人的理解:

其实就是利用归并的思想,三个数组或更多个数组做归并排序,排在最小的元素向前移动,计算最大最小元素之间的间隔,这样当一个数组用尽的时候,记录的最小间隔即为所求。

/*************************************************************************
        > File Name: mindiff.c
        > Author: desionwang
        > Mail: wdxin1322@qq.com 
        > Created Time: Wed 23 Oct 2013 02:57:44 PM CST
 ************************************************************************/


#include<stdio.h>


int mindiff(int a[], int size_a, int b[], int size_b, int c[], int size_c){
        int i = 0, j = 0 ,k = 0;
        int minnum;
        int mindiff = 65535;
        if(a == NULL || b == NULL || c == NULL){
                return -1;
        }
        if(size_a <= 0 || size_b <= 0 || size_c <= 0){
                return -1;
        }
        int max, min, diff;
        int index;
        while(i < size_a && j < size_b && k < size_c){
                printf("a:%d\tb:%d\tc:%d\n", a[i], b[j], c[k]);
                if(a[i] >= b[j]){
                        if(a[i] >= c[k]){
                                max = a[i];
                        }else{
                                max = c[k];
                        }
                        if(b[j] <= c[k]){
                                min = b[j];
                                index = j;
                                j++;
                        }else{
                                min = c[k];
                                index = k;
                                k++;
                        }
                }else{
                        if(b[j] >= c[k]){
                                max = b[j];
                        }else{
                                max = c[k];
                        }
                        if(a[i] <= c[k]){
                                min = a[i];
                                index = k;
                                i++;
                        }else{
                                min = c[k];
                                index = i;
                                k++;
                        }
                }


                printf("max:%d\tmin:%d\n", max, min);
                //printf("a:%d\tb:%d\tc:%d\n", a[i], b[j], c[k]);
                diff = max - min;
                if(diff < mindiff){
                        mindiff = diff;
                }
        }
        //printf("a:%d\tb:%d\tc:%d\n", a[i], b[j--], c[k]);
        printf("mindiff:%d\n", mindiff);
        return mindiff;


}


int main(){
        int a[5] = {4, 10, 15, 24, 26};
        int b[] = {0, 9, 12, 20};
        int c[] = {5, 18, 22, 30};
        mindiff(a, 5, b, 4, c , 4);
}



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

求k个数组包含每个数组至少一个元素的最小范围(待字闺中,备忘) 的相关文章

随机推荐

  • 6678开发板NDK网口通信完整实现(附源码)

    写在前面 1 已经有很多前辈做过很优秀的记录 本篇尽量讲得详细一点 能够让新手直接上手 2 在整个调试过程中 会遇到各种各样的问题 如果遇到问题请看第四部分 大部分问题应该能解决掉 不能解决的就评论区留言 3 我的CCS安装路径是 C Ti
  • simpleitk 读数据 图像 dicom nii 处理数据

    最近在使用 simpleITK 读取dicom nii 处理数据 非常方便 下面记录一下 1 读取DICOM序列 医学图像中一个CT序列包含很多张图片 即一个case包含许多slice 使用SimpleITK可以直接读取一个序列 impor
  • 基于微信小程序的电影院订票选座系统

    随着数据库技术和无线互联网的发展 各行业的数据信息量快速增多 正是由于这种发展形势 数据量变得非常杂乱无序 必须通过信息系统来选择用户需要的信息 本文通过微信小程序平台上研发电影院订票选座系统 解决部分电影院只能通过实体前台订票选座问题 本
  • BUCK BOOST学习总结

    首先对于我这种电源方面的小白来说 关于电源用的最多的就是线性稳压了 开关类的如 TI 的TPS系列 我是只知道应用电路而不知道具体原理的 但是长此以往也不是个办法 于是今天就带打家详细的来讲一下 BUCK BOOST电路的原理 先挂几个连接
  • JavaScript中的实例对象与函数对象、回调函数、JavaScript的error处理

    区别实例对象与函数对象 实例对象 new 函数产生的对象 称为实例对象 简称为对象函数 函数对象 将函数作为对象使用时 简称为函数对象 function Fn Fn函数 const fn new Fn Fn是构造函数 fn是实例对象 简称为
  • Windows10下TELEDYNE DALSA相机连接电脑以及网卡配置教程

    文章目录 一 相机IP地址设置 二 网卡端口设置 一 相机IP地址设置 右键相机 选择Scan Network 选择SHOW Status Dialog Box 出现发现的设备 设备显示为红色说明连接有问题 这里有两种解决办法 一种是以下文
  • QT button样式-边界宽度颜色设置

    1 QT QSS设置按钮边界样式 QT设置按钮边界样式 本学习添加三个按钮来做研究 QVBoxLayout vbox new QVBoxLayout QWidget w new QWidget this this gt setCentral
  • 安卓ShapeDrawable基本属性

    shape android shape rectangle oval line ring 可以设置为矩形 椭圆形 线性和环形 corners corners 用来定义圆角 有以下可用属性 android radius android top
  • 迷人的MCU单片机

    迷人的MCU单片机 MCU Microcontroller Unit 微控制单元 又称单片微型计算机 Single Chip Microcomputer 简称单片机 是把中央处理器 Central Process Unit CPU 的频率与
  • 智能驾驶数据集 合集

    智能驾驶数据集 集合 智能驾驶图像数据 No 1 103 300张驾驶员行为标注数据 驾驶员行为标注数据 总数据量103 300张 车内摄像头拍摄 且采集多年龄段 多时段 多种驾驶行为 关键点标注准确率不低于95 手势矩形框 人脸属性信息标
  • C++左值和右值

    这里有个误区 左值不是 left value 而是 location value 可寻址的值 右值不是 right value 而是 read value 只可读的值 所以 变量地址可读可写的是左值 只可读的是右值
  • 我的 Python.color() (Python 色彩打印控制)

    我的CSDN主页 My Python 学习个人备忘录 我的HOT博 自学并不是什么神秘的东西 一个人一辈子自学的时间总是比在学校学习的时间长 没有老师的时候总是比有老师的时候多 华罗庚 我的 Python color Python 色彩打印
  • 如何快速构造两个hashCode相同的字符串

    这要从hashCode的源码说起 String类hashCode的代码如下所示 public int hashCode int h hash if h 0 value length gt 0 char val value for int i
  • 【建议收藏】自动化测试框架开发教程

    在自动化测试项目中 为了实现更多功能 我们需要引入不同的库 框架 首先 你需要将常用的这些库 框架都装上 pip install requests pip install selenium pip install appium pip in
  • java 实现复制文件到指定目录

    将resource下的目录及文件 复制一份到指定目录 代码实现 import cn hutool core io FileUtil import org springframework core io Resource import org
  • adb shell 出现 insufficient permissions for device 参考网址:http://hi.baidu.com/iceliushuai/blog/item/1e50

    adb shell 出现 insufficient permissions for device 参考网址 http hi baidu com iceliushuai blog item 1e506160c5d01f48eaf8f801 h
  • 归纳演绎出的世界观

    题目略有写宽泛 刚读完 世界观 第一部分的内容 信息量有点大 迫切需要写篇读书笔记理清思路 归纳 和 演绎 方法 什么是归纳 Inductive 和演绎 Deductive 很多对于归纳 演绎的观点都是错误的 错误的以为两者是对立的 要么是
  • Spring MVC Controller配置方式

    Spring MVC 入门示例http cuisuqiang iteye com blog 2042931中 配置Controller时使用的是URL对应Bean的方式在SpringMVC中 对于Controller的配置方式有很多种 如下
  • Python—re正则表达式

    1 首先需导入模块import re 2 在一串字符中 findall方法可以获取全部能够匹配的片段 并把结果放在一个列表中 书写方式 re findall 正则表达式 规定匹配规则 被匹配的对象 3 使用findall方法匹配普通字符 4
  • 求k个数组包含每个数组至少一个元素的最小范围(待字闺中,备忘)

    有k个有序的数组 请找到一个最小的数字范围 使得这k个有序数组中 每个数组都至少有一个数字在该范围中 例如 1 4 10 15 24 26 2 0 9 12 20 3 5 18 22 30 所得最小范围为 20 24 其中 20在2中 22