题目:
给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。
请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
示例 1:
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
示例 2:
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
个人思路:
没思路
官方答案推荐:
①求中位数可视为求第k小的数。计算出中位数所在位置k,每次取两数组k//2位置的数来比较,小的一方则为中位数前的部分数据,移出数组,更新k,继续循环比较。原理:A[k/2]
最多是第 k-1
小的数,所以可排除之前的数。
②使用分割法分割两个数组为四部分,使max(ALeftMax,BLeftMax)和min(ARightMin,BRightMin)之间的数为中位数。保证左右分割后长度相同,ALeftMax<BRightMin,BLeftMax<ARightMin。
奇偶的问题:可将数组拉伸成2x+1的长度,视为两数之间添入空数字,每个数/2可变回原来位置。割在数上两边各分一个,割在空数字上则正常左右分配。得到公式:LeftMax = (curIndex-1)/2,RightMin = curIndex/2。此时两数组长度和为2m+2n+2,找到m+n+1和m+n+2位置的数即可。代码实际使用时直接用公式,所以可当空数字不存在。
二分法:找个长度短的数组进行,设为A数组。则ALeftMax>BRightMin时,mid--,BLeftMax>ARightMin,mid++
python代码:
import sys
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
nums1Length = len(nums1)
nums2Length = len(nums2)
#保证nums1是短的
if nums1Length > nums2Length:
return self.findMedianSortedArrays(nums2,nums1)
nums1LMax = nums2LMax = nums1RMin = nums2RMin = nums1Mid = nums2Mid = 0
nums1Low = 0
#放大成2倍
nums1High = 2 * nums1Length
while nums1Low <= nums1High:
#总和是m+n+1个,mid为索引值
nums1Mid = (nums1Low + nums1High)//2
nums2Mid = nums1Length + nums2Length - nums1Mid
#当某数组数值全在中值左边或右边时,代表中值肯定在另一数组,令LMax<RMin
nums1LMax = -sys.maxsize if nums1Mid == 0 else nums1[(nums1Mid-1)//2]
nums2LMax = -sys.maxsize if nums2Mid == 0 else nums2[(nums2Mid-1)//2]
nums1RMin = sys.maxsize if nums1Mid == 2*nums1Length else nums1[nums1Mid//2]
nums2RMin = sys.maxsize if nums2Mid == 2*nums2Length else nums2[nums2Mid//2]
#二分查找
if(nums1LMax > nums2RMin):
nums1High = nums1Mid - 1
elif(nums2LMax > nums1RMin):
nums1Low = nums1Mid + 1
else:
break
return (max(nums1LMax,nums2LMax)+min(nums1RMin,nums2RMin))/2
反思:
太难了。。。
保证A数组最短方法,判断长度,之后该函数参数的A、B互换