【解析】LeetCode4.寻找两个正序数组的中位数

题目要求:给定两个数组,求两个数组合并之后的中位数。限制时间复杂度为log(m+n)。


那么不难想到,我们合并然后排序,找到中间的元素就可以了,
如果长度是偶数,那么找到k/2和k/2+1个元素求平均数
如果是奇数,那么找到第(k+1)/2个元素
但是题目已经限制了时间复杂度,是log(m+n)
那么首先就可以想到这是一个折半查找的模型,二分模型每次查找都缩小查找的范围更新查找的目标。
如果要查第k小的元素,那么分别对两个数组的下标为[k/2-1]的元素(因为数组下标是从0开始的所以取半还要减去1)进行判断。假定这两个数组为A,B:那么如果A数组这个位置的元素比B数组的小的话,那么这个位置的元素包括这个位置前面的元素都不可能是第k个小的元素了,因为我们所取的已经有比他们大的元素了。那我们就将这些肯定不是的排除掉,刚好就排除了比k小的k/2个元素,最后就相当于是求第k/2个最小的元素。
如果取p=k/2,那么就相当于又进行判断,两个数组的第[p/2-1]个位置的比较,而被拆掉部分元素的数组下标就需要对应地加上k/2。这样反复地判断,直到k最后等于1为止,k到了1的时候该比第k个元素小的元素都已经排除出去了,那么我们就求最后一次迭代的两个数组首元素,看哪个更小,就是第k小的元素。

完整代码如下:


class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        total = len(nums1) + len(nums2)
        if total % 2 == 1:
            midIndex = total / 2  + 1
            res = self.getE(nums1,nums2,midIndex)
            return float(res)
        else:
            a = self.getE(nums1,nums2,total/2)
            b = self.getE(nums1,nums2,total/2 + 1)
            return (a+b) / 2.0
    
    def getE(self,nums1,nums2,k):
        len1 = len(nums1)
        len2 = len(nums2)
        index1 = 0
        index2 = 0
        while True:
            if index1 == len1:#数组元素都取完了
                return nums2[index2 + k -1]
            if index2 == len2:
                return nums1[index1 + k -1]
            if k == 1 :
                return min(nums1[index1],nums2[index2])
            new_index1 = min(index1 + k / 2,len1) - 1
            new_index2 = min(index2 + k / 2,len2) - 1
            pivot1 = nums1[new_index1]
            pivot2 = nums2[new_index2]
            if pivot1<=pivot2:
                k -= (new_index1 - index1 + 1)
                index1 = new_index1 + 1
            else:
                k -= (new_index2 - index2 + 1)
                index2 = new_index2 + 1


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值