程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

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

发布于2019-08-22 17:51     阅读(757)     评论(0)     点赞(6)     收藏(0)


给定两个大小为 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

1 暴力合并 ——— 双指针每次拿出最小的 O n1+n2 —— 不满足时复:log n1+n2

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        
        left_first = 0
        right_first = 0
        left_len = len(nums1)
        right_len = len(nums2)

        results = []

        while left_first < left_len and right_first < right_len:
            if nums1[left_first] < nums2[right_first]:
                results.append(nums1[left_first])
                left_first += 1
            elif nums1[left_first] >= nums2[right_first]:
                results.append(nums2[right_first])
                right_first += 1
        '''一定有一个列表先取完,另一个剩>=1个节点'''
        if left_first == left_len:  # 第2个列表先结束
            results += nums2[right_first:]
        elif right_first == right_len:  # 第1个列表先结束
            results += nums1[left_first:]
        ans = 0
        sumLen = left_len + right_len
        if sumLen % 2 == 0:
            tmp = (sumLen // 2) - 1
            ans = (results[tmp] + results[tmp+1]) / 2
        elif sumLen % 2 == 1:
            ans = results[sumLen // 2]

        return ans
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

2 [好背a] 分割线 + 二分查找 ———— O log m+n

强迫症击破:
1.让电脑自动识别条件,遇到什么if条件情况干什么即可,你不用管中间过程,最后符合 2个中位数的性质即可
     i j为0 或 n 时候,电脑自动if识别条件时会下标越界,所以你暴力直接拎出来告诉电脑该怎么 办即可
2 i j 为 0 nm时候:一定是最终的正确情况,此时时一方列表的所有元素全部大于或小于另一个列表中的所有元素
     【mh自猜:二分查找如果选到了0或n首尾,一定是最终结果了,因为如果它继续找的话要在中间才可以】
         另一个卡点:注意一方到头,另一方可不到头而是在中间,要用i j变量来动态访问max min,千万别用 0 n m 常数
    在这里插入图片描述
3 你不用担心一方到头是否左右对半分,j=f(i)的公式确保一定是对半分
    每个i对应的j是唯一的,所以当i到0或n的时候,j只有一个位置

def findMedianSortedArrays(nums1, nums2):
    """
    :type nums1: List[int]
    :type nums2: List[int]
    :rtype: float
    """
    n1 = len(nums1)
    n2 = len(nums2)
    # 保证第一个列表长
    if n1 > n2:
        n1,n2=n2,n1
        nums1,nums2=nums2,nums1

    imin = 0
    imax = n1

    while imin <= imax:  # 最后min=max 找到i 中位数直接在while里面算了方便
        i = (imin + imax) // 2
        j = (n1 + n2 + 1) // 2 - i

        if i < n1 and j > 0 and nums2[j-1] > nums1[i]:
            '''i太左'''
            imin += 1
        elif i > 0 and j < n2 and nums1[i-1] > nums2[j]:
            '''i太右'''
            imax -= 1
        else:
            '''i到达正确位置[注意:i=0 n 、j=0 m 一定是到最终位置了,因为此时是一个列表的所有元素都小于or大于另一个列表,你不用担心会左右数量不等,因为j的通过i的公式算出的,一定会两方对半分 ]'''
            # 左边的最值 [ij为0时候下标为负数越界,所以单独处理]
            if i == 0:
                max_of_left = nums2[j-1]
            elif j == 0:
                max_of_left = nums1[i-1]
            else:
                max_of_left = max(nums1[i-1], nums2[j-1])
            '''奇数不用考虑右边'''
            if (n1+n2)%2 == 1:
                return max_of_left

            if i == n1:
                min_of_right = nums2[j]  # 重要:i=n1时j在哪不一定,可不是nums1[0],应该写变量j
            elif j == n2:
                min_of_right = nums1[i]
            else:
                min_of_right = min(nums1[i], nums2[j])
            # '''偶数情况'''
            return (max_of_left + min_of_right)/2.0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47


所属网站分类: 技术文章 > 博客

作者:fggfg

链接:https://www.pythonheidong.com/blog/article/53327/01a769097317f78bbd6d/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

6 0
收藏该文
已收藏

评论内容:(最多支持255个字符)