news 2026/5/1 7:41:18

寻找两个正序数组的中位数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
寻找两个正序数组的中位数

class Solution {

public:

int getKthElement(const vector<int>& nums1, const vector<int>& nums2, int k) {

int m = nums1.size();

int n = nums2.size();

int index1 = 0, index2 = 0;

while (true) {

// 边界情况

if (index1 == m) {

return nums2[index2 + k - 1];

}

if (index2 == n) {

return nums1[index1 + k - 1];

}

if (k == 1) {

return min(nums1[index1], nums2[index2]);

}

// 正常情况

int newIndex1 = min(index1 + k / 2 - 1, m - 1);

int newIndex2 = min(index2 + k / 2 - 1, n - 1);

int pivot1 = nums1[newIndex1];

int pivot2 = nums2[newIndex2];

if (pivot1 <= pivot2) {

k -= newIndex1 - index1 + 1;

index1 = newIndex1 + 1;

}

else {

k -= newIndex2 - index2 + 1;

index2 = newIndex2 + 1;

}

}

}

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {

int totalLength = nums1.size() + nums2.size();

if (totalLength % 2 == 1) {

return getKthElement(nums1, nums2, (totalLength + 1) / 2);

}

else {

return (getKthElement(nums1, nums2, totalLength / 2) + getKthElement(nums1, nums2, totalLength / 2 + 1)) / 2.0;

}

}

};

使用归并的方式,合并两个有序数组,得到一个大的有序数组。大的有序数组的中间位置的元素,即为中位数。

不需要合并两个有序数组,只要找到中位数的位置即可。由于两个数组的长度已知,因此中位数对应的两个数组的下标之和也是已知的。维护两个指针,初始时分别指向两个数组的下标 0 的位置,每次将指向较小值的指针后移一位(如果一个指针已经到达数组末尾,则只需要移动另一个数组的指针),直到到达中位数的位置。

假设两个有序数组的长度分别为 m 和 n,上述两种思路的复杂度如何?

第一种思路的时间复杂度是 O(m+n),空间复杂度是 O(m+n)。第二种思路虽然可以将空间复杂度降到 O(1),但是时间复杂度仍是 O(m+n)。

如何把时间复杂度降低到 O(log(m+n)) 呢?如果对时间复杂度的要求有 log,通常都需要用到二分查找,这道题也可以通过二分查找实现。

根据中位数的定义,当 m+n 是奇数时,中位数是两个有序数组中的第 (m+n)/2 个元素,当 m+n 是偶数时,中位数是两个有序数组中的第 (m+n)/2 个元素和第 (m+n)/2+1 个元素的平均值。因此,这道题可以转化成寻找两个有序数组中的第 k 小的数,其中 k 为 (m+n)/2 或 (m+n)/2+1。

假设两个有序数组分别是 A 和 B。要找到第 k 个元素,我们可以比较 A[k/2−1] 和 B[k/2−1],其中 / 表示整数除法。由于 A[k/2−1] 和 B[k/2−1] 的前面分别有 A[0..k/2−2] 和 B[0..k/2−2],即 k/2−1 个元素,对于 A[k/2−1] 和 B[k/2−1] 中的较小值,最多只会有 (k/2−1)+(k/2−1)≤k−2 个元素比它小,那么它就不能是第 k 小的数了。

因此我们可以归纳出三种情况:

如果 A[k/2−1]<B[k/2−1],则比 A[k/2−1] 小的数最多只有 A 的前 k/2−1 个数和 B 的前 k/2−1 个数,即比 A[k/2−1] 小的数最多只有 k−2 个,因此 A[k/2−1] 不可能是第 k 个数,A[0] 到 A[k/2−1] 也都不可能是第 k 个数,可以全部排除。

如果 A[k/2−1]>B[k/2−1],则可以排除 B[0] 到 B[k/2−1]。

如果 A[k/2−1]=B[k/2−1],则可以归入第一种情况处理。

可以看到,比较 A[k/2−1] 和 B[k/2−1] 之后,可以排除 k/2 个不可能是第 k 小的数,查找范围缩小了一半。同时,我们将在排除后的新数组上继续进行二分查找,并且根据我们排除数的个数,减少 k 的值,这是因为我们排除的数都不大于第 k 小的数。

有以下三种情况需要特殊处理:

如果 A[k/2−1] 或者 B[k/2−1] 越界,那么我们可以选取对应数组中的最后一个元素。在这种情况下,我们必须根据排除数的个数减少 k 的值,而不能直接将 k 减去 k/2。

如果一个数组为空,说明该数组中的所有元素都被排除,我们可以直接返回另一个数组中第 k 小的元素。

如果 k=1,我们只要返回两个数组首元素的最小值即可。

用一个例子说明上述算法。假设两个有序数组如下:

A: 1 3 4 9
B: 1 2 3 4 5 6 7 8 9
两个有序数组的长度分别是 4 和 9,长度之和是 13,中位数是两个有序数组中的第 7 个元素,因此需要找到第 k=7 个元素。

比较两个有序数组中下标为 k/2−1=2 的数,即 A[2] 和 B[2],如下面所示:

A: 1 3 4 9

B: 1 2 3 4 5 6 7 8 9

由于 A[2]>B[2],因此排除 B[0] 到 B[2],即数组 B 的下标偏移(offset)变为 3,同时更新 k 的值:k=k−k/2=4。

下一步寻找,比较两个有序数组中下标为 k/2−1=1 的数,即 A[1] 和 B[4],如下面所示,其中方括号部分表示已经被排除的数。

A: 1 3 4 9

B: [1 2 3] 4 5 6 7 8 9

由于 A[1]<B[4],因此排除 A[0] 到 A[1],即数组 A 的下标偏移变为 2,同时更新 k 的值:k=k−k/2=2。

下一步寻找,比较两个有序数组中下标为 k/2−1=0 的数,即比较 A[2] 和 B[3],如下面所示,其中方括号部分表示已经被排除的数。

A: [1 3] 4 9

B: [1 2 3] 4 5 6 7 8 9

由于 A[2]=B[3],根据之前的规则,排除 A 中的元素,因此排除 A[2],即数组 A 的下标偏移变为 3,同时更新 k 的值: k=k−k/2=1。

由于 k 的值变成 1,因此比较两个有序数组中的未排除下标范围内的第一个数,其中较小的数即为第 k 个数,由于 A[3]>B[3],因此第 k 个数是 B[3]=4。

A: [1 3 4] 9

B: [1 2 3] 4 5 6 7 8 9

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 5:10:06

2006-2024年上市公司创新投入、创新产出、创新效率指标数据

创新投入&#xff1a;指的是企业在技术创新、新产品研发、新工艺探索等方面的投入。 创新投入强度&#xff1a;公司年度研发出占总资产的比例、公司年度研发出占营业收入的比例。 创新产出&#xff1a;指的是在研发过程中取得的创新成果&#xff0c;如专利技术或者新产品。发…

作者头像 李华
网站建设 2026/5/1 5:11:36

Dify智能体平台可视化界面连接Qwen3-VL-8B教程

Dify智能体平台可视化界面连接Qwen3-VL-8B教程 在电商客服系统中&#xff0c;用户上传一张商品图片并提问&#xff1a;“这个包包适合通勤吗&#xff1f;”传统的图像分类模型只能识别出“手提包”这样的标签&#xff0c;而无法理解“通勤”这一语义场景。如何让AI真正“看懂”…

作者头像 李华
网站建设 2026/5/1 5:09:22

基于C#与三菱FX5U PLC实现以太网通信

一、硬件配置方案 1. PLC参数设置&#xff08;GX Works3&#xff09; 1. 网络配置- 模块选择&#xff1a;内置以太网端口&#xff08;需FX5U-CNV-ADP适配器&#xff09;- IP地址&#xff1a;192.168.0.10&#xff08;需与PC同网段&#xff09;- 端口号&#xff1a;5002&#xf…

作者头像 李华
网站建设 2026/4/15 18:16:48

告别手动回复,拥抱高效沟通:微信智能小助手上线

还在为繁杂的消息回复而烦恼吗&#xff1f;重复问题一再解答&#xff0c;客户咨询一多便应接不暇&#xff1f;现在&#xff0c;只需三分钟设置&#xff0c;你的微信就能拥有24小时在线的智能自动回复助手&#xff01;不论图文、语音还是视频消息&#xff0c;这款助手皆可智能识…

作者头像 李华
网站建设 2026/5/1 6:09:15

如何在消费级GPU上运行Qwen3-8B:高效低成本的大模型实践

如何在消费级GPU上运行Qwen3-8B&#xff1a;高效低成本的大模型实践 在AI技术飞速演进的今天&#xff0c;大语言模型已经不再是少数机构的专属工具。越来越多的开发者、研究者和创业者开始尝试将LLM集成到自己的产品或实验中。然而&#xff0c;现实却常常令人望而却步——动辄…

作者头像 李华
网站建设 2026/4/29 18:36:21

使用Docker安装Qwen3-8B镜像,快速搭建本地大模型环境

使用Docker安装Qwen3-8B镜像&#xff0c;快速搭建本地大模型环境 在如今AI技术飞速发展的背景下&#xff0c;越来越多的开发者希望能在自己的机器上运行大语言模型——不是为了炫技&#xff0c;而是真正用于实验、原型开发甚至产品化。但现实往往很骨感&#xff1a;下载模型权…

作者头像 李华