C++&Python 描述 LeetCode 4. 寻找两个正序数组的中位数

  大家好,我是亓官劼(qí guān jié ),在【亓官劼】公众号、GitHub、B站、华为开发者论坛等平台分享一些技术博文。放弃不难,但坚持一定很酷!时光荏苒,未来可期,加油~

  如果喜欢博主的文章可以关注博主的个人公众号【亓官劼】(qí guān jié),如果有需要找博主的话可以在公众号后台留言。建了个小交流群,Q群:545611263。

C++&Python 描述 LeetCode 4. 寻找两个正序数组的中位数_数组


  《leetcode刷题系列》,博主将从第一题开始,每天更新当日的刷题情况,每题博主会尽量加一些解题思路的分析和C++&python代码的实现。每日在微信公众号【亓官劼】定时更新,有兴趣一起刷题的小伙伴可以关注公众号来一起卷起来呀。

  同时文章在GitHub中进行了开源,内含本系列文章目前已刷的各个题解和解题思路,GitHub地址为:​​LeetCode​​,如果文章对你有帮助的话可以来GitHub点个star,如果有更好的解题思路的话,也可以来GitHub提交~一起改进

题目

给定两个大小分别为 ​​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