寻找两个正序数组的中位数-二分查找4

python

一. 无脑傻瓜版本:

没看答案

1.把两个数组合并成一个数组并排序;
2.找到新数组的中位数。

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        ls = list()
        for i in nums1:
            ls.append(i)
        for j in nums2:
            ls.append(j)
        
        ls.sort()
        num = len(ls)
        a = 0
        if num % 2 == 0:
            a = (ls[num//2-1] + ls[num//2])/2
        else:
            a = ls[num//2]
        return a

复杂度分析:

  • 时间复杂度和空间复杂度都是O(m+n)。

二. 二分查找:

主要思路:

  • 要找到第 k (k>1) 小的元素,那么就取 prior1 = nums1[k//2-1] 和 prior2 = nums2[k//2-1] 进行比较;

  • nums1 中小于等于 prior1 的元素有 nums1[0 … k//2-2] 共计 k//2-1 个,nums2 中小于等于 prior2 的元素有 nums2[0 … k//2-2] 共计 k//2-1 个;

  • 取 prior = min(prior1, prior2),两个数组中小于等于 prior 的元素共计不会超过 (k//2-1) + (k//2-1) ≤ k-2 个,这样 prior 本身最大也只能是第 k-1 小的元素(即prior1=prior2的时候);

  • 如果 prior = prior1,那么 nums1[0 … k//2-1] 都不可能是第 k 小的元素。把这些元素全部"删除",剩下的作为新的 nums1 数组(即指针移动到k//2位置),如果 prior= prior2,那么 nums2[0 … k//2-1] 都不可能是第 k 小的元素,把这些元素全部 “删除”,剩下的作为新的 nums2 数组(即指针移动到k//2位置);

  • 由于我们 “删除” 了一些元素(这些元素都比第 k 小的元素要小),因此需要修改 k 的值,减去删除元素的个数。

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        m, n = len(nums1), len(nums2)
        def getKthitem(k):
            index0, index1 = 0, 0 # nums1 和 nums2 的指针位置
            while True:
                if index0 == m:
                    return nums2[index1 + k - 1]
                if index1 == n:
                    return nums1[index0 + k - 1]
                if k == 1:
                    return min(nums1[index0], nums2[index1])
                
                newindex0 = min(index0 + k//2 - 1, m-1) # 二分查找,且防止越界
                newindex1 = min(index1 + k//2 - 1, n-1) # 二分查找,且防止越界
                prior1, prior2 = nums1[newindex0], nums2[newindex1]
                if prior1 <= prior2: # 一次只对一个数组进行操作
                    k -= newindex0 - index0 + 1 # k减去删除元素的个数
                    index0 = newindex0 + 1 # “删除”元素
                else:
                    k -= newindex1 - index1 + 1 # k减去删除元素的个数
                    index1 = newindex1 + 1 # “删除”元素

        totallength = m + n
        if totallength % 2 == 0:
            return (getKthitem(totallength//2) + getKthitem(totallength//2+1))/2
        else:
            return getKthitem(totallength//2+1)

复杂度分析:

  • 时间复杂度:O(log(m+n)),其中 m 和 n 分别是数组 nums1 和 nums2 的长度。
  • 空间复杂度:O(1)。

猜你喜欢

转载自blog.csdn.net/VaccyZhu/article/details/113741906