LeetCode笔记

两个排序数组的中位数

2018-05-02  本文已影响14人  只为此心无垠

看时间复杂度的要求,首先想到的就是二分法,但是如何在两个数组上进行二分呢?我们把这个问题分解一下,先求解在两个有序数组中查找整体第k大的数,如果m+n是偶数,则调用两次子过程求平均,如果是奇数,调用一次。我们这样来找第k大的数:

假设m和n都大于k/2,则比较nums1[k/2 - 1]和nums2[k - k/2 - 1]
如果前者比较大,则可以扔掉nums2[k - k/2 - 1]之前的k/2个数
如果后者比较大,则可以扔掉nums1[k/2 - 1]之前的k/2个数
如果相等,说明第k个数已经找到
如果m和n中有一个小于k/2呢?假设n比m小,那么就取min(k/2, n)和k - min(k/2, n)作为比较的下标值。
时间复杂度是O(log(k))。在写代码的过程中,边界判断是非常容易出错的,要反复练习。


def findMedianSortedArrays(self, A, B):
        n = len(A) + len(B)
        if n % 2 == 1:
            return self.findKth(A, B, n / 2 + 1)
        else:
            smaller = self.findKth(A, B, n / 2)
            bigger = self.findKth(A, B, n / 2 + 1)
            return (smaller + bigger) / 2.0

    def findKth(self, A, B, k):
        if len(A) == 0:
            return B[k - 1]
        if len(B) == 0:
            return A[k - 1]
        if k == 1:
            return min(A[0], B[0])
        
        a = A[k / 2 - 1] if len(A) >= k / 2 else None
        b = B[k / 2 - 1] if len(B) >= k / 2 else None
        
        if b is None or (a is not None and a < b):
            return self.findKth(A[k / 2:], B, k - k / 2)
        return self.findKth(A, B[k / 2:], k - k / 2)
上一篇 下一篇

猜你喜欢

热点阅读