面试中算法(找到两个数组的中位数)

有两个升序数组,如何找出这两个数组归并以后新的升序数组的中位数?

中位数把一个升序数组分成了长度相等的两部分,其中左半部分的最大值永远小于或等于右半部分的最小值。

如上图所示,对于偶数长度的数组,可以根据中位数分成长度相等的两部分,左半部分的最大元素(6),永远小于或等于右半部分的最小元素(7)。

如上图所示,对于奇数长度的数组,如果把中位数本身归入左半部分,则左半边长度=右半边长度+1。 左半部分的最大元素(5),永远小于或等于右半部分的最小元素(6)。

假设:

数组A的长度是m,绿色和橙色元素的分界点是i,

数组B的长度是n,绿色和橙色元素的分界点是j,

那么为了让大数组的左右两部分长度相等,则i和j需要符合如下两个条件:

i+j= (m+n+1)/2 (之所以m+n后面+1,是为了应对大数组长度为奇数情况。)

Max(A[i-1],Blj-1])<= Min(A[i], B[j])(就是最大的绿色元素小于或等于最小的橙色元素。)

由于m+n的值是恒定的,所以我们只要确定一个合适的i,就可以确定j,从而找到大数组左半部分和右半部分的分界,也就找到了归并之后大数组的中位数。

其中i可以利用“二分查找”的思想。 

如下图所示:

第一步:就如二分查找那样,把i设在数组A的正中位置 i=3:

第二步:根据i的值来确定j的值,j= (m+n+1)/2 -i = 5:

 

 第三步: 验证i和j,分为下面三种情况:

1、B[j-1]≤A[i]&& A[i-1]≤B[j] 说明i和j左侧的元素都小于或等于右侧的元素。

2、A[i]<B[j-1] 说明i对应的元素偏小了,i应该向右侧移动。

3、A[i-1]>B[j] 说明i-1对应的元素偏大了,i应该向左侧移动。

显然,图中的属于情况2,A[3]< B[5],所以i应该向右移动。

第四步:在数组A的右半部分,重新确定i的位置,就像二分查找一样:

第五步:同第二步,根据i的值来确定j的值,j= (m+n+1)/2-i = 3: 

 

第六步:同第三步,验证i和j: 由于A[5] >=B[2]且B[3]>=A[4],所以这一组i和j是合适的!

第七步:找出中位数:

如果大数组的长度是奇数

中位数= Max (A[i-1],B[j-1]>)   (大数组左半部分的最大值。)

如果大数组的长度是偶数

中位数= (Max (A[i-1],B[j-1]) +Min(A[i],B[i]))/2   

(大数组左半部分的最大值和大数组右半部分的最小值取平均。)

在图示:大数组的长度是奇数,所以中位数=Max (8,12)=12。

特殊情况:

1、数组A的长度远大于数组B 

     可以提前把数组A和数组B进行交换,较短的数组放在前面,i从较短的数组中取。由于数组A是较短数组,i的搜索次数减少了。

2、无法找到合适的i值

 (1)数组A的长度<数组B的长度,并且数组A的所有元素都>数组B的元素。

可以跳出二分查找的循环,所求的中位数是B[j-1]。(仅限奇数情况) 

(2)数组A的长度<数组B的长度,并且数组A的所有元素都<数组B的元素。

可以跳出二分查找的循环,所求的中位数是Max (A[i-1],B[j-1])。(仅限奇数情况)

def get_middle_number(arrA,arrB):#获取数组的大小m,n=len(arrA),len(arrB)#判断arrA大小>=arrB大小,则交换if m>n:arrA,arrB, m,n,=arrB,arrA,n,m#如果n为0,值异常if n==0:raise  ValueError#起点,终点,中间start,end,half=0,m,(m+n+1)//2#循环while start<=end:i=(start+end)//2j=half-i# 验证i和j,三种情况if i<m and arrB[j-1]>arrA[i]:#(1) i偏小了,需要右移start=i+1elif i>0 and arrA[i-1]>arrB[j]:#(2) i偏大了,需要左移end=i-1else:#(3) i刚好合适,或i已达到数组边界if i == 0:max_of_left = arrB[j - 1]elif j == 0:max_of_left = arrA[i - 1]else:max_of_left = max(arrA[i - 1], arrB[j - 1])if (m + n) % 2 == 1:# 如果大数组的长度是奇数,中位数就是左半部分的最大值return max_of_leftif i == m:min_of_right = arrB[j]elif j == n:min_of_right = arrA[i]else:min_of_right = min(arrA[i], arrB[j])# 如果大数组的长度是偶数,取左侧最大值和右侧最小值的平均return (max_of_left + min_of_right) / 2.0if __name__ == '__main__':arrA = list([3, 5, 6, 7, 8, 15, 20])arrB = list([1, 10, 12, 18,21,24,25,29])print(get_middle_number(arrA,arrB))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3030088.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

一文了解webpack和vite中Tree-Shaking

1、什么是Tree-Shaking 1.1 摇树优化&#xff08;Tree Shaking&#xff09;是Webpack中一种用于优化JavaScript代码的技术。它的目标是通过静态分析&#xff0c;从代码中剔除未被使用的模块&#xff0c;从而减少最终打包文件的大小。 1.2 Tree-shaking 它的名字来源于通过摇晃…

物联网技术在数字化工厂中的应用,你知道多少?——青创智通

工业物联网解决方案-工业IOT-青创智通 物联网&#xff08;IoT&#xff09;技术在数字化工厂的应用正日益成为工业革命的重要推动力。随着科技的飞速发展&#xff0c;物联网技术不断革新&#xff0c;其在数字化工厂中的应用也呈现出愈发广泛和深入的态势。本文将详细探讨物联网…

传输层之 TCP 协议

TCP协议段格式 源/目的端口号&#xff1a;表示数据是从哪个进程来&#xff0c;到哪个进程去。 序号&#xff1a;发送数据的序号。 确认序号&#xff1a;应答报文的序号&#xff0c;用来回复发送方的。 4 位首部长度&#xff1a;一个 TCP 报头&#xff0c;长度是可变的&#xff…

Android 屏幕适配全攻略(上)-掌握屏幕单位,应对千变万化的设备

本文从 Android 开发中常见的长度单位 px、dp、sp 入手&#xff0c;详细介绍了它们的特点及转换关系。 接着深入探讨了屏幕尺寸、分辨率、像素密度等重要的屏幕指标&#xff0c;帮助读者全面理解它们之间的联系。最后&#xff0c;通过实例代码演示了如何在代码中进行单位转换&…

第一章 buffer cache管理 - 2 原理机制

本章节主要介绍缓冲区管理器机制&#xff0c;从原理上介绍共享缓冲区如何管理内存页。 1、缓冲区管理器的结构 PostgreSQL缓冲区管理器由缓冲区hash表、缓冲区buffer描述符和缓冲池组成。下面依次介绍这几个结构。 1.1 缓冲区标签 typedef struct buftag {RelFileNode rnod…

Python运维之协程

目录 一、定义协程 二、并发 三、异步请求 协程是一种轻量级的线程&#xff0c;它通过保存和恢复寄存器上下文和栈来实现调度切换&#xff0c;从而保留函数执行的状态。 这种机制使得协程在处理I/O密集型任务时效率较高&#xff0c;因为它们可以在I/O操作期间让出CPU&#…

5g视频彩信和普通彩信有什么区别

5G视频彩信和普通彩信有什么区别 随着科技的不断进步&#xff0c;手机通信技术也在迅速发展。5G技术的出现&#xff0c;为彩信传输提供了更高的速度和更广的带宽。在这种背景下&#xff0c;5G视频彩信和普通彩信成为了人们关注的焦点。本文将探讨这两种彩信的区别。 5G视频彩信…

Java数组的应用---选择排序(Select Sort)

一、需求&#xff1a;选择排序(Select Sort)&#xff0c;进行升序显示 在一组排列中把最大的数取出来放在一个新的列表里&#xff0c;再删去&#xff0c;在取最大的数出来&#xff0c;依次类推直到取到最后一个数字 二、定义一个无序的一维数组&#xff0c;并输出数组 程序运…

BBS客户端服务器的编写

根据网络编程中的内容&#xff0c;我们本篇文章将讲解一个bbs通信的项目&#xff0c;首先让我们了解一下什么是bbs. 一、bbs介绍 BBS&#xff0c;即Bulletin Board System的缩写&#xff0c;中文译为“电子公告板系统”或“网络论坛”。它是一个在网络上进行信息交流和讨论的…

重装前端整体流程

用户管理 --汇总 -- 明细-CSDN博客 一、node 这个看环境变量 2023最新版Node.js下载安装及环境配置教程&#xff08;非常详细&#xff09;从零基础入门到精通&#xff0c;看完这一篇就够了_nodejs安装及环境配置-CSDN博客 配置到国内镜像的时候&#xff0c;去看&#xff0c;淘…

代码随想录算法训练营第六十二天|503.下一个更大元素II、42.接雨水

代码随想录算法训练营第六十二天|503.下一个更大元素II、42.接雨水 503.下一个更大元素II 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元…

小程序(三)

十三、自定义组件 &#xff08;二&#xff09;数据方法声明位置 在js文件中 A、数据声明位置&#xff1a;data中 B、方法声明位置methods中&#xff0c;这点和普通页面不同&#xff01; Component({/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {isCh…

【系统架构师】-案例篇(七)信息安全

某软件公司拟开发一套信息安全支撑平台&#xff0c;为客户的局域网业务环境提供信息安全保护。该支撑平台的主要需求如下&#xff1a; 1.为局域网业务环境提供用户身份鉴别与资源访问授权功能&#xff1b; 2.为局域网环境中交换的网络数据提供加密保护&#xff1b; 3.为服务…

26、Qt使用QFontDatabase类加载ttf文件更改图标颜色

一、图标下载 iconfont-阿里巴巴矢量图标库 点击上面的链接&#xff0c;在打开的网页中搜索自己要使用的图标&#xff0c;如&#xff1a;最大化 找到一个自己想用图标&#xff0c;选择“添加入库” 点击“购物车”图标 能看到刚才添加的图标&#xff0c;点击“下载代码”(需要…

js教程(13)

一、作用域 作用域规定了变量能够被访问的范围&#xff0c;而离开变量作用域的变量则不能被访问&#xff08;有时也叫变量的生命周期&#xff09;。作用域又分为局部作用域和全局作用域。 1.局部作用域 在函数或代码块内部声明的变量只能在其内部被访问&#xff0c;在外部无法…

牛客周赛 Round 41 C-F

C 小红的循环移位 思路&#xff1a; 一个数是不是四的倍数&#xff0c;只用看最后两位是否能够整除4即可。 #include <bits/stdc.h>using namespace std; const int N 1e6 5; typedef long long ll; typedef pair<ll, ll> pll; typedef array<ll, 3> p3;…

暗区突围进不去/游戏无法启动/掉帧卡顿/报错的解决方法

暗区突围是一款高拟真硬核射击手游&#xff0c;打造了全新的沉浸式暗区战局体验&#xff0c;发行商是腾讯公司。这个游戏名词虽然看起来有些陌生&#xff0c;但其本身的玩法内核毫无疑问的是&#xff0c;这款游戏在画面质量和枪械操作方面&#xff0c;都是手游市场上同类游戏中…

【vulhub靶场】Apache 中间件漏洞复现

【vulhub靶场】Apache 中间件漏洞复现 一、Apache HTTPD 换行解析漏洞&#xff08;CVE-2017-15715&#xff09;1. 漏洞详情2. 影响版本3. 漏洞复现 二、Apache多后缀解析漏洞&#xff08;apache_parsing_vulnerability&#xff09;1. 漏洞详情2. 漏洞复现 三、Apache HTTP Serv…

【LLM 论文】Step-Back Prompting:先解决更高层次的问题来提高 LLM 推理能力

论文&#xff1a;Take a Step Back: Evoking Reasoning via Abstraction in Large Language Models ⭐⭐⭐⭐ Google DeepMind, ICLR 2024, arXiv:2310.06117 论文速读 该论文受到的启发是&#xff1a;人类再解决一个包含很多细节的具体问题时&#xff0c;先站在更高的层次上解…

第8章.STM32开发方式(库函数)介绍

目录 0. 《STM32单片机自学教程》专栏 8.1 单片机的开发方式 8.1.1 直接操作寄存器 8.1.2 使用库函数 8.2 STM32的库函数 8.2.1 标准外设库(STD库) 8.2.2 HAL库 8.2.3 LL库 0. 《STM32单片机自学教程》专栏 本文作为专栏《STM32单片机自学教程》专栏其中的一…