leecode4. 寻找两个有序数组的中位数

马上就要开始吧找工作啦,本科没有刷leecode,现在开始刷题啦!每天一道题,坚持下去,加油吧!

一、题目:leecode4. 寻找两个有序数组的中位数:

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

二、思路:不是我想的,我只是采用别人最好的思路:

这道题如果时间复杂度没有限定在 O(log(m+n))O(log(m+n))O(log(m+n)),我们可以用 O(m+n)O(m+n)O(m+n) 的算法解决,用两个指针分别指向两个数组,比较指针下的元素大小,一共移动次数为 (m+n + 1)/2,便是中位数。

首先,我们理解什么中位数:指的是该数左右个数相等。

比如:odd : [1,| 2 |,3],2 就是这个数组的中位数,左右两边都只要 1 位;

even: [1,| 2, 3 |,4],2,3 就是这个数组的中位数,左右两边 1 位;

那么,现在我们有两个数组:

num1: [a1,a2,a3,...an]

nums2: [b1,b2,b3,...bn]

[nums1[:left1],nums2[:left2] | nums1[left1:], nums2[left2:]]

只要保证左右两边 个数 相同,中位数就在 | 这个边界旁边产生。

如何找边界值,我们可以用二分法,我们先确定 num1 取 m1 个数的左半边,那么 num2 取 m2 = (m+n+1)/2 - m1 的左半边,找到合适的 m1,就用二分法找。

当 [ [a1],[b1,b2,b3] | [a2,..an],[b4,...bn] ]

我们只需要比较 b3 和 a2 的关系的大小,就可以知道这种分法是不是准确的!

例如:我们令:

nums1 = [-1,1,3,5,7,9]

nums2 =[2,4,6,8,10,12,14,16]

当 m1 = 4,m2 = 3 ,它的中位数就是median = (num1[m1] + num2[m2])/2

时间复杂度:O(log(min(m,n)))O(log(min(m,n)))O(log(min(m,n)))

对于代码中边界情况,大家需要自己琢磨。

三、代码:

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        n1  =len(nums1)
        n2 = len(nums2)
        if(n1 > n2):
            return self.findMedianSortedArrays(nums2, nums1)
        k = (n1 + n2 + 1)//2
        left = 0
        right = n1
        while(left < right):
            m1 = left + (right - left)//2
            m2 = k - m1
            if(nums1[m1] < nums2[m2-1]):
                left = m1 + 1
            else:
                right = m1
        m1 = left
        m2 = k - m1
        c1 = max(nums1[m1-1] if(m1 > 0) else float("-inf"), nums2[m2-1] if(m2 > 0) else float("-inf"))
        if((n1 + n2)%2 == 1):
            return(c1)
        c2 = min(nums1[m1] if(m1 < n1) else float("inf"), nums2[m2] if(m2 < n2) else float("inf"))
        return (c1 + c2)/2

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值