📜  门|门 CS 1996 |第 61 题(1)

📅  最后修改于: 2023-12-03 15:12:45.840000             🧑  作者: Mango

门|门 CS 1996 |第 61 题

这道题目是门|门 CS 1996年考试的第61题,属于算法题目。题目描述如下:

给定两个升序排列的整数数列 a,b,长度分别为 n,m。求出这两个数列的中位数。

例如:a=1,3,5,7,9,b=2,4,6,8,中位数为5。

这道题目要求的是两个有序数组的中位数,其实就是求这两个数组的合并后的中位数。这里我们提供两种解法:

解法一 - 二分查找
思路

由于两个数组升序排列,所以我们可以先对其进行合并。然后再根据长短位置的奇偶性来判断中位数的位置,最后返回中位数即可。

对于合并后的有序数组,我们可以使用二分查找的思路寻找中位数。

代码实现
def findMedianSortedArrays(nums1, nums2):
    # 合并两个有序数组
    nums1.extend(nums2)
    nums1.sort()

    n = len(nums1)
    mid = n // 2

    # 根据长短位置的奇偶性来判断中位数的位置
    if n % 2 == 0:
        return (nums1[mid-1] + nums1[mid]) / 2
    else:
        return nums1[mid]
时间复杂度

由于使用了排序算法,所以时间复杂度为 $O\left((n+m)\log(n+m)\right)$。

解法二 - 双指针法
思路

我们可以使用双指针的方式遍历两个有序数组,找到中位数的位置。

假设两个数组的长度分别为 n 和 m,让 i, j 分别表示两个数组的遍历位置。由于是寻找中位数,所以需要找到中位数的位置,也就是第 (n+m+1)/2 个位置。

在遍历时,如果 n+m 是奇数,那么找到的那个位置就是中位数。如果是偶数,那么需要再找到一个数,取两数平均值作为中位数。

代码实现
def findMedianSortedArrays(nums1, nums2):
    m, n = len(nums1), len(nums2)
    left, right = (m + n + 1) // 2, (m + n + 2) // 2

    def get_kth_element(k):
        i, j = 0, 0
        while True:
            if i == m:
                return nums2[j + k - 1]
            if j == n:
                return nums1[i + k - 1]
            if k == 1:
                return min(nums1[i], nums2[j])

            new_i = min(i + k // 2, m) - 1
            new_j = min(j + k // 2, n) - 1

            if nums1[new_i] > nums2[new_j]:
                k -= new_j - j + 1
                i = new_i + 1
            else:
                k -= new_i - i + 1
                j = new_j + 1

    return (get_kth_element(left) + get_kth_element(right)) / 2
时间复杂度

由于使用了双指针算法,所以时间复杂度为 $O\left(n+m\right)$。

以上两种解法都可以求出给定两个升序排列的整数数列的中位数,选择哪种解法可以根据具体情况选择。