给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log (m+n)) 。来源:力扣(L

这段代码定义了一个名为findMedianSortedArrays的函数,它接收两个已排序的数组nums1和nums2作为参数。首先,它将两个数组合并并排序,然后通过取排序后数组中间两个元素的平均值来计算中位数。该方法适用于找到两个有序数组的合并中位数。
var findMedianSortedArrays = function(nums1, nums2) {
   let a = nums1.concat(nums2).sort((a, b) => a - b)
    return (a[Math.floor(a.length / 2) ] + a[Math.ceil(a.length / 2) - 1]) / 2
};

解法一:暴力合两个数组成一个有序数,然后根据数组长度的奇偶性返回中位数时间复杂度:O((m+n)log(m+n)),其中 m n 分别是两个数组的长度,排需要 O((m+n)log(m+n)) 的时间。 空间复杂度:O(m+n),需要一个额外的数组存储两个数组后的结果。 解法二:二分查找 根据中位数的定义,当 m+n 为奇数时,中位数两个序数中的第 (m+n)/2 个元素;当 m+n 为偶数时,中位数两个序数中的第 (m+n)/2 个元素(m+n)/2+1 个元素的平均值。因此,可以考虑使用二分查找的方法查找第 k 小的元素。 我们假设两个数组的长度分别为 m n,且 m<=n,需要在 nums1 nums2 两个序数中找到第 k 小的元素。首先,设 i=min(m,k/2),j=k-i,则有 nums1[i-1]<=nums2[j-1]。如果 nums1[i-1]>nums2[j-1],那么 nums2[0...j-1] 中的所有元素都小于第 k 小的元素,可以将这些元素全部排除。因为第 k 小的元素不可能在 nums2[0...j-1] 中,否则 nums2[0...j-1] 中就已经有 k 个元素了,而 nums1 中只有 i-1 个元素小于 nums1[i-1]。因此,可以将 nums2[0...j-1] 排除,更新 k 的值为 k-j。同理,如果 nums1[i-1]<=nums2[j-1],那么 nums1[0...i-1] 中的所有元素都小于第 k 小的元素,可以将这些元素全部排除,更新 k 的值为 k-i。 时间复杂度:O(log(m+n)),其中 m n 分别是两个数组的长度,每次循环可以排除当前 k/2 个元素,因此循环次数为 O(log(m+n))。 空间复杂度:O(1),只需要常数级别的额外空间。 参考代码: class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int m = nums1.size(); int n = nums2.size(); int left = (m + n + 1) / 2; // 如果 m+n 是奇数,则中位数是第 (m+n)/2+1 个元素;如果是偶数,则中位数是第 (m+n)/2(m+n)/2+1 个元素的平均值 int right = (m + n + 2) / 2; // 如果 m+n 是奇数,则中位数是第 (m+n)/2+1 个元素;如果是偶数,则中位数是第 (m+n)/2(m+n)/2+1 个元素的平均值 return (findKth(nums1, 0, m - 1, nums2, 0, n - 1, left) + findKth(nums1, 0, m - 1, nums2, 0, n - 1, right)) / 2.0; } int findKth(vector<int>& nums1, int start1, int end1, vector<int>& nums2, int start2, int end2, int k) { int len1 = end1 - start1 + 1; int len2 = end2 - start2 + 1; if (len1 > len2) { return findKth(nums2, start2, end2, nums1, start1, end1, k); } if (len1 == 0) { return nums2[start2 + k - 1]; } if (k == 1) { return min(nums1[start1], nums2[start2]); } int i = start1 + min(len1, k / 2) - 1; int j = start2 + min(len2, k / 2) - 1; if (nums1[i] > nums2[j]) { return findKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1)); } else { return findKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1)); } } };
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呱嗨喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值