Leetcode004. Median of Two Sorted Arrays

来源:互联网 发布:上海嘉桥数据咨询公司 编辑:程序博客网 时间:2024/05/16 15:20

题目描述:

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:

nums1 = [1, 3]nums2 = [2]The median is 2.0

Example 2:

nums1 = [1, 2]nums2 = [3, 4]The median is (2 + 3)/2 = 2.5

题目大意:

求两个有序数列的中位数。

思路:

刚看到这题时,想到的自然是排序然后直接取中间。因为两个数组都有序,自然想到归并排序,O(n)的复杂度也几乎能AC所有的算法题。

但这题还有O(logn)的解法,运用的是二分的思想。

这个方法是求两个有序数组的第k小数的通法。首先,把a,b数组的第k/2个比较,若a[k/2]>b[k/2],则b数组的前k/2个一定不是第k小数,因为a、b数组k/2以后的数都比它更大。所以把b[1~k/2]删去,求剩下的第k/2小数。

这一刀删去了许多冗余的比较,使算法速度有了很大提升。

在这个算法中,每次把k减小一半,所以时间复杂度是O(log(k/2)),相当于O(logn)。

代码:

归并排序:

class Solution(object):    def findMedianSortedArrays(self, nums1, nums2):        """        :type nums1: List[int]        :type nums2: List[int]        :rtype: float        """        a = []        i = j = 0        totlen = len(nums1) + len(nums2)        while i < len(nums1) and j < len(nums2):            if nums1[i] < nums2[j]:                a.append(nums1[i])                i = i + 1            else:                a.append(nums2[j])                j = j + 1        a.extend(nums1[i:]) # 剩下的数一定是最大的那部分,全放进数组        a.extend(nums2[j:])        if totlen % 2:            return a[totlen // 2]        else:            return (a[totlen // 2 - 1] + a[totlen // 2]) / 2
二分(python):
def findkth(A, B, k): # 返回A数组和B数组中的第k小值    m = len(A)    n = len(B)    if m > n:        return findkth(B, A, k) # 确保A比B短,方便处理    if not m:        return B[k - 1] # 如果A数组为空返回B数组第k小值    if k == 1:        return min(A[0], B[0]) # k=1直接出解    pa = min(k / 2, m) # 考虑到m<k/2的情况    pb = k - pa    if A[pa - 1] < B[pb - 1]:        return findkth(A[pa:], B, k - pa) # 把A的前pa个删掉    else:        return findkth(A, B[pb:], k - pb) # 把B的前pb个删掉class Solution(object):    def findMedianSortedArrays(self, nums1, nums2):        """        :type nums1: List[int]        :type nums2: List[int]        :rtype: float        """        tlen = len(nums1) + len(nums2)        if tlen % 2:            return findkth(nums1, nums2, tlen // 2 + 1)        else:            return (findkth(nums1, nums2, tlen // 2) + findkth(nums1, nums2, tlen // 2 + 1)) / 2 # 两个中位数的平均值        

二分(c++):

int kth(int k, vector<int> &a, int sa, vector<int> &b, int sb){    if (a.size() - sa > b.size() - sb)        return kth(k, b, sb, a, sa);    if (sa == a.size())        return b[k - 1];    if (k == 1)        return min(a[sa], b[sb]);    int ta = min(k / 2, int(a.size() - sa)),tb = k - ta;    if (a[sa + ta - 1] < b[sb + tb - 1])        return kth(k - ta, a, sa + ta, b, sb);    else        return kth(k - tb, a, sa, b, sb + tb);}class Solution {public:    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {        int len = nums1.size() + nums2.size();        if (len % 2)            return kth(len / 2 + 1, nums1, 0, nums2, 0);        else            return (kth(len / 2, nums1, 0, nums2, 0) +                 kth(len / 2 + 1, nums1, 0, nums2, 0)) / 2.0;    }};


原创粉丝点击