*************
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 = 1
(nums1
的长度)n = 8
(nums2
的长度)total_left = (1 + 8 + 1) // 2 = 5
(中位数左边应有 5 个元素)- 二分查找范围:
left = 0
,right = 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
)
- 左边:
检查分割条件:
nums1_left <= nums2_right
→-∞ <= 7
✅nums2_left <= nums1_right
→6 <= 1
❌
调整二分范围:
由于 nums2_left > nums1_right
(6 > 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
)
- 左边:
检查分割条件:
nums1_left <= nums2_right
→1 <= 6
✅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