
中位数本质:
- 把序列分为左右两半,左右两半元素个数相等,或者左边多1
- 左边的数 < 右边的数
暴力解法
clike
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
#nums=nums1.append(nums2)
# 使用 + 号连接两个列表,这会返回一个新的列表
nums = nums1 + nums2
nums.sort()
total = len(nums1) + len(nums2)
if total %2 ==0: # 偶数
return (nums[total//2] + nums[total//2 -1]) / 2
else:
return nums[total//2]
合并排序后取中位数
时间复杂度 O(m+n), 不符合题目 O(log (m+n)) 要求
双指针计数法,不需要真的合并
线性扫描 → 时间复杂度 O(m+n),空间复杂度O(1)
把指针推进到总数一半位置
clike
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
# 模拟 merge(归并两个有序数组),只走到中位数位置,时间复杂度O(m+n)
m = len(nums1)
n = len(nums2)
total = m + n
p1 = p2 = 0 # 双指针
curr = 0 # 当前值(初值是啥没关系,会被覆盖)
# 5个数的中位数是第3个,4个数的中位数是第2,3个,所以要走到total // 2 + 1
for i in range(total // 2 + 1):
prev = curr # 每次移动前,先保存上一次的结果prev
# 谁小移动谁
if p1 < m: # 如果 nums1 还没走完
if p2 >= n: # 情况 A:nums2 走完了,只剩下nums1
curr = nums1[p1]
p1 += 1
elif nums1[p1] <= nums2[p2]: # 情况 B:还有nums2,但是nums1值更小
curr = nums1[p1]
p1 += 1
else: # 情况 C:还有nums2,而且nums2值更小
curr = nums2[p2]
p2 += 1
# 如果 nums1 走完了,只能拿 nums2 的
else:
curr = nums2[p2]
p2 += 1
if total % 2 == 1: # 如果总数是奇数,返回 curr
return float(curr)
else:
return (prev + curr) / 2.0 # 如果总数是偶数,返回 (prev + curr) / 2
时间复杂度O(log (m+n))