力扣第4题 寻找两个正序数组的中位数 困难 合并暴力 求解c++ 有优化代码
题目
困难
给定两个大小分别为
m
和n
的正序(从小到大)数组nums1
和nums2
。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为
O(log (m+n))
。
示例 1:
输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4] 输出:2.50000 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
思路和解题方法
- 首先,创建一个空的vector ans,用于存储合并后的有序数组。
- 初始化四个指针:n1和n2分别指向nums1和nums2的起始位置,a1和a2分别记录已经合并到ans中的元素个数。
- 对nums1和nums2进行排序,使它们分别按升序排列。
- 在一个循环中,比较nums1[n1]和nums2[n2]指向的元素:
- 如果nums1[n1]大于等于nums2[n2],则将nums2[n2]加入ans中,同时将n2和a2递增1。
- 否则,将nums1[n1]加入ans中,同时将n1和a1递增1。
- 每一次比较操作都会向ans中添加一个元素。
- 循环结束后,判断是否还有剩余的元素未添加到ans中:
- 如果a1小于nums1的长度,说明nums1还有剩余元素未添加到ans中,将剩余元素全部添加到ans中。
- 如果a2小于nums2的长度,说明nums2还有剩余元素未添加到ans中,将剩余元素全部添加到ans中。
- 计算ans的长度n,并根据n的奇偶性来确定返回值:
- 如果n是奇数,返回ans[n/2]作为中位数。
- 如果n是偶数,返回(ans[n/2] + ans[(n+1)/2])/2.0作为中位数。
复杂度
时间复杂度:
O(m+n)
时间复杂度:在最坏情况下,该算法需要遍历两个输入数组
nums1
和nums2
,直到其中一个数组的所有元素都被处理完。因此,时间复杂度为 O(m+n),其中 m 和 n 分别是nums1
和nums2
的长度。
空间复杂度
O(m+n)
空间复杂度:这段代码使用了一个额外的数组
ans
来存储合并后的有序数组,其长度为 m+n。因此,空间复杂度为 O(m+n)。
优化前 c++ 代码(优化后代码在后面)
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
vector<int> ans; // 用于存储合并后的有序数组
int n1 = 0, n2 = 0; // 分别指向 nums1 和 nums2 当前比较的元素索引
int a1 = 0, a2 = 0; // 记录已经合并到 ans 的元素个数
while (n1 < nums1.size() && n2 < nums2.size()) { // 当两个数组都还有元素可以比较时
if (nums1[n1] >= nums2[n2]) { // 如果 nums1 当前的元素大于等于 nums2 当前的元素
ans.push_back(nums2[n2]); // 将 nums2 当前的元素添加到 ans 中
n2++; // nums2 指针后移
a2++; // 已合并到 ans 的元素个数加一
}
else { // 如果 nums1 当前的元素小于 nums2 当前的元素
ans.push_back(nums1[n1]); // 将 nums1 当前的元素添加到 ans 中
n1++; // nums1 指针后移
a1++; // 已合并到 ans 的元素个数加一
}
}
if (a1 < nums1.size()) { // 如果 nums1 还有剩余元素未添加到 ans 中
for (a1; a1 < nums1.size(); a1++) {
ans.push_back(nums1[a1]); // 将剩余的 nums1 元素添加到 ans 中
}
}
else if (a2 < nums2.size()) { // 如果 nums2 还有剩余元素未添加到 ans 中
for (a2; a2 < nums2.size(); a2++) {
ans.push_back(nums2[a2]); // 将剩余的 nums2 元素添加到 ans 中
}
}
int n = ans.size() - 1; // 合并后的有序数组的最后一个元素索引
if (ans.size() % 2 == 1) { // 如果合并后的数组长度为奇数
return ans[n / 2] / 1.0; // 返回中间元素作为中位数(由于除法运算,转换为浮点数)
}
else { // 如果合并后的数组长度为偶数
return (ans[n / 2] + ans[(n + 1) / 2]) / 2.0; // 返回中间两个元素的平均值作为中位数
}
}
};
优化后c++代码
class Solution {
public:
double findMedianSortedArrays(const vector<int>& nums1, const vector<int>& nums2) {
vector<int> ans; // 用来存储合并后的有序数组
int n1 = 0, n2 = 0; // 分别表示遍历 nums1 和 nums2 的指针
// 合并两个有序数组,直到其中一个数组的所有元素都被处理完
while (n1 < nums1.size() && n2 < nums2.size()) {
// 比较当前指针位置的元素,将较小的元素添加到 ans 中,并将相应指针向后移动一位
ans.push_back(nums1[n1] >= nums2[n2] ? nums2[n2++] : nums1[n1++]);
}
// 将剩余未处理的元素添加到 ans 中
for (; n1 < nums1.size(); n1++) {
ans.push_back(nums1[n1]);
}
for (; n2 < nums2.size(); n2++) {
ans.push_back(nums2[n2]);
}
int n = ans.size() - 1;
int medianIndex = n / 2; // 计算中位数的索引位置
// 如果 ans 的长度为奇数,返回中间的元素;如果长度为偶数,返回中间两个元素的平均值
return (ans[medianIndex] + ans[n - medianIndex]) / 2.0;
}
};
觉得有用的话可以点点赞,支持一下。
如果愿意的话关注一下。会对你有更多的帮助。
每天都会不定时更新哦 >人< 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)