当前位置: 首页 > news >正文

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

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

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 = 0j = 0#开始合并两个listif nums1[i] < nums2[j]:merged.append(nums1[i])i = i + 1else:merged.append(nums2[j])j = j + 1# 将剩下的元素添加到merged中merged.extend(nums1[i:]) #   : 表示从i到末尾的elementsmerged.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 = 0j = 0#开始合并两个listif nums1[i] < nums2[j]:merged.append(nums1[i])i = i + 1else:merged.append(nums2[j])j = j + 1# 将剩下的元素添加到merged中merged.extend(nums1[i:]) #   : 表示从i到末尾的elementsmerged.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 = 0j = 0#开始合并两个listwhile i < len(nums1) and j < len(nums2):if nums1[i] < nums2[j]:merged.append(nums1[i])i = i + 1else:merged.append(nums2[j])j = j + 1# 将剩下的元素添加到merged中merged.extend(nums1[i:]) #   : 表示从i到末尾的elementsmerged.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       = 0right      = mtotal_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       = 0right      = mtotal_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       = 0right      = mtotal_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       = 0right      = mtotal_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.0elif nums1_left > nums2_right:right = i - 1else: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

相关文章:

  • 【BotSharp详细介绍——一步步实现MCP+LLM的聊天问答实例】
  • vscode c++编译onnxruntime cuda 出现的问题
  • 浏览器宝塔访问不了给的面板地址
  • 运维职业发展思维导图
  • 幼儿学前教育答辩词答辩技巧问题答辩自述稿
  • React Native/Flutter 原生模块开发
  • BGP实验(联邦及反射器)
  • SQL:MySQL函数:条件函数(Conditional Functions)
  • Day 21 训练
  • Spring+LangChain4j小智医疗项目
  • 如何让open-mpi在不同版本的OS上运行
  • java方法的练习题
  • Python内存管理:赋值、浅拷贝与深拷贝解析
  • 数智管理学(九)
  • 【匹配】Smith-Waterman
  • 【高频面试题】LRU缓存
  • JavaScript - 运算符之逗号操作符与逗号分隔符(逗号操作符概述、逗号操作符用法、逗号分隔符、逗号分隔符用法)
  • Miniconda介绍介绍和使用
  • Unix Bourne Shell
  • 已解决(亲测有效!):安装部署Docker Deskpot之后启动出现Docker Engine Stopped!
  • 中方是否计划解除或调整稀土出口管制?外交部回应
  • 中国结算澄清“严查场外配资”传闻:账户核查为多年惯例,无特殊安排
  • 商务部新闻发言人就出口管制管控名单答记者问
  • 马上评|“衣服越来越难买”,对市场是一个提醒
  • 崔登荣任国家游泳队总教练
  • 山西临汾哪吒主题景区回应雕塑被指抄袭:造型由第三方公司设计