寻找两个正序数组的中位数 - 困难

*************

Python

topic: 4. 寻找两个正序数组的中位数 - 力扣(LeetCode)

*************

Give the topic an inspection.

Do the old topic will give you some new sparks. Before that, I do some really good craetive things about my logo. It will used at the very begin at my travel vlog. I am excited to do this little things. Maybe one shoot in my vedio costs me some time to figure it out. Recording makes me feel real in my life. I think the most time of my year is without ripples. But some moments light the boring days. I wil never forget the day I stood at the 5276 meters altitude. Nor will I forget the day I saw so many fish swimming next to me at the bottom of the sea. I love that moments. I am about to plan my travel to Xinjiang next mounth. I am so excited about the commoing travel.

Back to the topic, the first thing is to merge the two list.

1、merge the two lists

the basic usage of adding element in the end of the list is very easy.

nums = [1, 2, 3]

# append只能加一个
nums.append(4)       # 输出: [1, 2, 3, 4]

# extend可以加一串
nums.extend([4, 5])  # 输出: [1, 2, 3, 4, 4, 5]

and in the program I can use both of them.

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        merged = [] #创建一个新的list,并初始化为空
        i = 0
        j = 0

        #开始合并两个list
        if nums1[i] < nums2[j]:
            merged.append(nums1[i])
            i = i + 1
        else:
            merged.append(nums2[j])
            j = j + 1
        
        # 将剩下的元素添加到merged中
        merged.extend(nums1[i:]) #   : 表示从i到末尾的elements
        merged.extend(nums2[j:])
            

Then find the one right in the middle of the line.

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        merged = [] #创建一个新的list,并初始化为空
        i = 0
        j = 0

        #开始合并两个list
        if nums1[i] < nums2[j]:
            merged.append(nums1[i])
            i = i + 1
        else:
            merged.append(nums2[j])
            j = j + 1
        
        # 将剩下的元素添加到merged中
        merged.extend(nums1[i:]) #   : 表示从i到末尾的elements
        merged.extend(nums2[j:])
            
        # 找到中间那个
        length = len(merged)
        if length % 2 == 1:
            return merged[length // 2] # //是整数除法的意思
        else:
            return (merged[length // 2 - 1] + merged[length // 2]) / 2.0

something wrong as usual.

ai tell me that line 22 went wrong. add the loop.

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        merged = [] #创建一个新的list,并初始化为空
        i = 0
        j = 0

        #开始合并两个list
        while i < len(nums1) and j < len(nums2):
            if nums1[i] < nums2[j]:
                merged.append(nums1[i])
                i = i + 1
            else:
                merged.append(nums2[j])
                j = j + 1
        
        # 将剩下的元素添加到merged中
        merged.extend(nums1[i:]) #   : 表示从i到末尾的elements
        merged.extend(nums2[j:])
            
        # 找到中间那个
        length = len(merged)
        if length % 2 == 1:
            return merged[length // 2] # //是整数除法的意思
        else:
            return (merged[length // 2 - 1] + merged[length // 2]) / 2.0

this code works well, but . If you notice that, you will ask what is time complexity.

iterate through the array: i = 0 -> n  O(n)

嵌套i次: O(n的几次方)

二分查找:O(log n)

so this topic tell you that you have to use the dichotomy to solve the problem. Make sure that the shorter one stands ahead.

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        # 短的数组要在前面
        if len(nums1) > len(nums2):
            nums1, nums2 = nums2. nums1
        
        # 初始化两个指针,用于二分法查找
        m          = len(nums1)
        n          = len(nums2)
        left       = 0
        right      = m
        total_left = (m + n + 1) / 2

Then make pointer i and point j stand just at the middle of the line. pointer i is kind of knife, i cuts the whole array which tears the array apart.

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        # 短的数组要在前面
        if len(nums1) > len(nums2):
            nums1, nums2 = nums2. nums1
        
        # 初始化两个指针,用于二分法查找
        m          = len(nums1)
        n          = len(nums2)
        left       = 0
        right      = m
        total_left = (m + n + 1) / 2

        # 让两个指针先到中间站着位置
        while left <= right:
            i = (left + right) // 2 
            j = total_left - i

        # 处理边界问题

i = (left + right) // 2, pointer i could be land in nums1, also could be land in nums2.

i 是 nums1 左边部分的长度,j 是 nums2 左边部分的长度。

如果 nums2_left > nums1_right,说明 nums2 的左边太大,需减少 j(即增大 i)。

如果 nums1_left > nums2_right,说明 nums1 的左边太大,需减少 i

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        # 短的数组要在前面
        if len(nums1) > len(nums2):
            nums1, nums2 = nums2, nums1
        
        # 初始化两个指针,用于二分法查找
        m          = len(nums1)
        n          = len(nums2)
        left       = 0
        right      = m
        total_left = (m + n + 1) / 2 # 中位数左边应该有的元素个数

        # 让两个指针先到中间站着位置
        while left <= right:
            i = (left + right) // 2 
            j = total_left - i

        # 处理边界问题
         # 处理边界:当 i=0 时,nums1_left 无元素,设为 -∞;i=m 时,nums1_right 无元素,设为 +∞
            nums1_left = -float('inf') if i == 0 else nums1[i-1]
            nums1_right = float('inf') if i == m else nums1[i]
            
            # 同理处理 nums2 的边界
            nums2_left = -float('inf') if j == 0 else nums2[j-1]
            nums2_right = float('inf') if j == n else nums2[j]
class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        # 短的数组要在前面
        if len(nums1) > len(nums2):
            nums1, nums2 = nums2, nums1
        
        # 初始化两个指针,用于二分法查找
        m          = len(nums1)
        n          = len(nums2)
        left       = 0
        right      = m
        total_left = (m + n + 1) / 2 # 中位数左边应该有的元素个数

        # 让两个指针先到中间站着位置
        while left <= right:
            i = (left + right) // 2 
            j = total_left - i

        # 处理边界问题
         # 处理边界:当 i=0 时,nums1_left 无元素,设为 -∞;i=m 时,nums1_right 无元素,设为 +∞
            nums1_left = -float('inf') if i == 0 else nums1[i-1]
            nums1_right = float('inf') if i == m else nums1[i]
            
            # 同理处理 nums2 的边界
            nums2_left = -float('inf') if j == 0 else nums2[j-1]
            nums2_right = float('inf') if j == n else nums2[j]

            # 检查分割条件
            if nums1_left <= nums2_right and nums2_left <= nums1_right:
                if (m + n) % 2 == 1:
                    return max(nums1_left, nums2_left)
                else:
                    return (max(nums1_left, nums2_left) + min(nums1_right, nums2_right)) / 2.0
            elif nums1_left > nums2_right:
                right = i - 1
            else:
                left = i + 1

举个例子:

  • nums1 = [1](长度 m = 1
  • nums2 = [2, 3, 4, 5, 6, 7, 8, 9](长度 n = 8
1. 初始化变量
  • m = 1nums1 的长度)
  • n = 8nums2 的长度)
  • total_left = (1 + 8 + 1) // 2 = 5(中位数左边应有 5 个元素)
  • 二分查找范围:left = 0right = m = 1
2. 二分查找过程

第一次迭代

  • i = (left + right) // 2 = (0 + 1) // 2 = 0
  • j = total_left-i = 5-0 = 5

分割结果

  • nums1 的分割点 i = 0
    • 左边:[]nums1_left = -∞
    • 右边:[1]nums1_right = 1
  • nums2 的分割点 j = 5
    • 左边:[2, 3, 4, 5, 6]nums2_left = 6
    • 右边:[7, 8, 9]nums2_right = 7

检查分割条件

  1. nums1_left <= nums2_right → -∞ <= 7 ✅
  2. nums2_left <= nums1_right → 6 <= 1 ❌

调整二分范围
由于 nums2_left > nums1_right6 > 1),说明 nums2 的左边部分太大,需要减少 nums2 的左边元素数量。
因此,增大 i (让 nums1 贡献更多左边元素,从而减少 nums2 的左边元素):
left = i + 1 = 1

第二次迭代

  • i = (1 + 1) // 2 = 1
  • j = 5-1 = 4

分割结果

  • nums1 的分割点 i = 1
    • 左边:[1]nums1_left = 1
    • 右边:[]nums1_right = +∞
  • nums2 的分割点 j = 4
    • 左边:[2, 3, 4, 5]nums2_left = 5
    • 右边:[6, 7, 8, 9]nums2_right = 6

检查分割条件

  1. nums1_left <= nums2_right → 1 <= 6 ✅
  2. nums2_left <= nums1_right → 5 <= +∞ ✅

分割合法!此时:

  • 左边部分:[1] + [2, 3, 4, 5](共 5 个元素)
  • 右边部分:[] + [6, 7, 8, 9](共 4 个元素)
3. 计算中位数
  • 总长度 m + n = 9(奇数),中位数是左边部分的最大值:
    max(nums1_left, nums2_left) = max(1, 5) = 5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值