news 2026/10/29 23:15:26

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

作者头像

张小明

前端开发工程师

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/10/30 1:21:38

好用的窄带分拣机提供商

在当前的物流和制造业中&#xff0c;窄带分拣机已成为提高生产效率和降低运营成本的关键设备之一。然而&#xff0c;随着市场需求的不断变化和技术的快速迭代&#xff0c;企业在选择窄带分拣机时面临着诸多挑战。这些挑战不仅包括技术性能的选择&#xff0c;还包括对长期投资回…

作者头像 李华
网站建设 2026/10/30 5:07:58

Qwen3-14B与LangChain结合:打造企业级AI内容生成平台

Qwen3-14B与LangChain结合&#xff1a;打造企业级AI内容生成平台 在当今企业数字化转型的浪潮中&#xff0c;内容生产正面临前所未有的挑战——信息量爆炸式增长&#xff0c;而人力处理能力却难以跟上节奏。无论是月度运营报告、客户沟通邮件&#xff0c;还是产品发布新闻稿&am…

作者头像 李华
网站建设 2026/10/30 11:31:50

中小企业如何选择靠谱的软文发稿平台:精准投放与高效传播指南

在信息爆炸的数字时代&#xff0c;软文营销以其成本效益高、传播性强、受众接受度好的特点&#xff0c;成为中小企业推广策略中不可或缺的一环。然而&#xff0c;面对市场上琳琅满目的软文发稿平台&#xff0c;如何选择一家靠谱、高效的合作方&#xff0c;成为许多企业营销负责…

作者头像 李华
网站建设 2026/10/30 19:40:03

Qwen3-8B+PyTorch:实现快速本地推理的最优组合

Qwen3-8B PyTorch&#xff1a;如何在消费级设备上实现高效本地推理 在生成式AI迅猛发展的今天&#xff0c;越来越多开发者不再满足于调用云端API来“试玩”大模型。他们更关心一个问题&#xff1a;能不能把真正强大的语言模型&#xff0c;跑在自己的电脑上&#xff1f; 这个问…

作者头像 李华
网站建设 2026/10/29 21:40:42

git 下载大模型权重失败?教你正确获取Qwen3-32B文件

git 下载大模型权重失败&#xff1f;教你正确获取Qwen3-32B文件 在部署开源大模型时&#xff0c;你是否曾经历过这样的场景&#xff1a;满怀期待地执行 git clone https://github.com/Qwen/Qwen3-32B.git&#xff0c;结果几分钟后终端突然报错——“fatal: the remote end hun…

作者头像 李华
网站建设 2026/10/29 19:38:44

雷科电力-REKE-30kVA-10kV-5kV工频耐压试验装置

一、概述&#xff1a;雷科电力生产的REKE-30kVA/10kV/5kV智能工频耐压试验系统&#xff0c;该控制系统具有操作便捷&#xff0c;性能优使用安全可靠、外形美观、耐用、移动方便等特点。是供电企业、大型电力企业、冶金、发电厂、铁路等需要电力维修部门的常用的设备。本产品采用…

作者头像 李华