class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
def getKth(nums1,start1,end1,nums2,start2,end2,k):
# O(log(m+n)) O(1)
# 在两个数组中递归找第K个
# 记录当前列表的长度
len1 = end1-start1+1
len2 = end2-start2+1
# 确保总是一个小的数组,一个大的数组【长度】
if len1>len2:
return getKth(nums2,start2,end2,nums1,start1,end1,k)
if len1 == 0:
# 如果此时数组1的长度为0,直接在nums2中找即可
return nums2[start2+k-1]
if k==1:
# 如果此时只找1个元素,则直接返回当前两个数组中最小的
return min(nums1[start1],nums2[start2])
# 判断当前是否越界,就是第k小的数字已经超出当前数组长度了
i = start1 + min(len1,k//2)-1
j = start2 + min(len2,k//2)-1
# 找到第k个数字比较
if nums1[i] > nums2[j]:
return getKth(nums1,start1,end1,nums2,j+1,end2,k-(j-start2+1))
else:
return getKth(nums1,i+1,end1,nums2,start2,end2,k-(i-start1+1))
n = len(nums1)
m = len(nums2)
# 在两个数组找第k小
left = (n+m+1)//2
right = (n+m+2)//2
# 将奇数和偶数的情况合并,奇数会求两次同样的k
return (getKth(nums1,0,n-1,nums2,0,m-1,left)+getKth(nums1,0,n-1,nums2,0,m-1,right))*0.5
"""
# 官方题解
# - 主要思路:要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较
# - 这里的 "/" 表示整除
# - nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共计 k/2-1 个
# - nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共计 k/2-1 个
# - 取 pivot = min(pivot1, pivot2),两个数组中小于等于 pivot 的元素共计不会超过 (k/2-1) + (k/2-1) <= k-2 个
# - 这样 pivot 本身最大也只能是第 k-1 小的元素
# - 如果 pivot = pivot1,那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums1 数组
# - 如果 pivot = pivot2,那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums2 数组
# - 由于我们 "删除" 了一些元素(这些元素都比第 k 小的元素要小),因此需要修改 k 的值,减去删除的数的个数
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
def getKthElement(k):
index1, index2 = 0, 0
while True:
# 特殊情况
if index1 == m:
return nums2[index2 + k - 1]
if index2 == n:
return nums1[index1 + k - 1]
if k == 1:
return min(nums1[index1], nums2[index2])
# 正常情况
newIndex1 = min(index1 + k // 2 - 1, m - 1)
newIndex2 = min(index2 + k // 2 - 1, n - 1)
pivot1, pivot2 = nums1[newIndex1], nums2[newIndex2]
if pivot1 <= pivot2:
k -= newIndex1 - index1 + 1
index1 = newIndex1 + 1
else:
k -= newIndex2 - index2 + 1
index2 = newIndex2 + 1
m, n = len(nums1), len(nums2)
totalLength = m + n
if totalLength % 2 == 1:
return getKthElement((totalLength + 1) // 2)
else:
return (getKthElement(totalLength // 2) + getKthElement(totalLength // 2 + 1)) / 2
"""
每日一道Leetcode - 4. 寻找两个正序数组的中位数 【二分查找】
最新推荐文章于 2023-03-17 17:36:55 发布