LeetCode 4. 寻找两个正序数组的中位数
这个题目可以归结到寻找第k小(大)元素问题
思路可以总结如下:
取两个数组中的第k/2个元素进行比较,如果数组1的元素小于数组2的元素,则说明数组1中的前k/2个元素不可能成为第k个元素的候选,所以将数组1中的前k/2个元素去掉,组成新数组和数组2求第k-k/2小的元素,因为我们把前k/2个元素去掉了,所以相应的k值也应该减小。
另外就是注意处理一些边界条件问题,比如某一个数组可能为空或者k为1的情况。
比如当某一个数组的起始位置大于等于其数组长度时,说明其所有数字均已经被淘汰了,相当于一个空数组了,那么实际上就变成了在另一个数组中找数字,直接就可以找出来了。还有就是如果K=1的话,那么我们只要比较nums1和nums2的起始位置i和j上的数字就可以了。
我们使用一个小trick,我们分别找第 (m+n+1) / 2
个,和 (m+n+2) / 2
个,然后求其平均值即可,这对奇偶数均适用。加入 m+n 为奇数的话,那么其实 (m+n+1) / 2 和 (m+n+2) / 2 的值相等,相当于两个相同的数字相加再除以2,还是其本身。
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
len1, len2 = len(nums1), len(nums2)
left, right = (len1 + len2 + 1) // 2, (len1 + len2 + 2) // 2
return (self.findKthElement(nums1, nums2, left) + self.findKthElement(nums1, nums2, right))/2
def findKthElement(self, arr1, arr2, k):
len1, len2 = len(arr1), len(arr2)
if len1 > len2:
return self.findKthElement(arr2, arr1, k)
if not arr1:
return arr2[k - 1]
if k == 1:
return min(arr1[0], arr2[0])
i, j = min(k // 2, len1) - 1, min(k // 2, len2) - 1
if arr1[i] > arr2[j]:
return self.findKthElement(arr1, arr2[j + 1:], k - j - 1)
else:
return self.findKthElement(arr1[i + 1:], arr2, k - i - 1)