C++&Python 描述 LeetCode 4. 寻找两个正序数组的中位数
大家好,我是亓官劼(qí guān jié ),在【亓官劼】公众号、GitHub、B站、华为开发者论坛等平台分享一些技术博文。放弃不难,但坚持一定很酷!时光荏苒,未来可期,加油~
题目
给定两个大小分别为 m
和 n
的正序(从小到大)数组 nums1
和 nums2
。请你找出并返回这两个正序数组的 中位数 。
示例 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
示例 3:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
示例 4:
输入:nums1 = [], nums2 = [1]
输出:1.00000
示例 5:
输入:nums1 = [2], nums2 = []
输出:2.00000
提示:
-
nums1.length == m
-
nums2.length == n
-
0 <= m <= 1000
-
0 <= n <= 1000
-
1 <= m + n <= 2000
-
-106 <= nums1[i], nums2[i] <= 106
**进阶:**你能设计一个时间复杂度为 O(log (m+n))
的算法解决此问题吗?
解题思路
这里给定的nums1
和nums2
都是有序的,我们可以采用二路归并的方法来找到中间的1
或2
位数,以此来计算中位数。这里需要主要当有一端走到端点后,溢出情况的处理。
算法实现 C++
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int len1 = nums1.size(), len2 = nums2.size(), sum = len1 + len2, mid = (sum-1) / 2, i = 0, j = 0, res = 0;
while(i + j < mid){
// 有一端已经走到头的情况处理
if(j >= len2){
i++;
continue;
}
if(i >= len1){
j ++;
continue;
}
// 两端都还没到头的情况
if(nums1[i] < nums2[j]) i++;
else j++;
}
if(sum & 1){
// 奇数个的情况,只取一个即可返回
// 有一端到头的情况
if(i == len1 || j == len2) return i == len1 ? nums2[j] : nums1[i];
// 两端都在
return nums1[i] < nums2[j] ? nums1[i] : nums2[j];
}else{
// 偶数个的情况,取中间两个。
// 有一端到头的情况
if(i == len1 || j == len2) return i == len1 ? (nums2[j] + nums2[j+1]) / 2.0 : (nums1[i] + nums1[i+1])/2.0;
// 两端都在
res = nums1[i] < nums2[j] ? nums1[i++] : nums2[j++];
// 取完第一个数后有一端到头
if(i == len1 || j == len2) return i == len1 ? (res + nums2[j]) / 2.0 : (res + nums1[i]) / 2.0;
// 取完第一个数后两端都在
res += nums1[i] < nums2[j] ? nums1[i++] : nums2[j++];
return res / 2.0;
}
}
};
算法实现 Python
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
i = 0
j = 0
l1 = nums1.__len__()
l2 = nums2.__len__()
cnt = l1 + l2
mid = (cnt - 1) // 2
while i + j < mid:
if i >= l1:
j += 1
continue
if j >= l2:
i += 1
continue
if nums1[i] < nums2[j]: i += 1
else: j += 1
if cnt & 1:
# 奇数,中位数只有一个
# 当有一端走到头的时候
if i == l1 or j == l2: return nums2[j] if i == l1 else nums1[i]
# 两端都没走到头的时候
return nums1[i] if nums1[i] < nums2[j] else nums2[j]
# 总个数为偶数,中位数有两个
if i == l1 or j == l2: return (nums2[j] + nums2[j+1]) / 2 if i == l1 else (nums1[i] + nums1[i+1]) / 2
# 当前两端都没到头的情况
tmp = 0
if nums1[i] < nums2[j]:
tmp = nums1[i]
i += 1
else:
tmp = nums2[j]
j += 1
if i == l1 or j == l2: return (tmp + nums2[j]) / 2 if i == l1 else (tmp + nums1[i]) / 2
tmp += nums1[i] if nums1[i] < nums2[j] else nums2[j]
return tmp / 2