题目:
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
You may assume nums1 and nums2 cannot be both empty.
Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
题意:
给定两个已经排好序的数组,我们需要找到两个数组合起来之后的中位数。
解法
首先,我们可以使用直接把两个数组融合,但是这样的复杂度为O(n+m),比题目说提出的O(log(m+n))要大,
随意我们得使用别的方法
二分搜索法:
我们需要将两个数组分割,是它们的左半边相加的大小与右半边相加的大小一样,并且满足数组一的左边最大值小于或等于数组二右边的最小值,数组一右边的最小值大于或等于数组二左边的最大值
如以下所示:
array1= 1 , 3 , 8 , 9 ,11
array2 = 7 , 13 , 15 , 18, 19
成功分割后的结果:
array1 = 1 , 3 ,8 , 9 | 11
array2 = 7 | 13,15,18,19
这个时候求中位数就简单了,如果 两个数组长度之和为偶数,只需要找到左边最大值和右边最小值除2就行
如果为奇数,取左半边最大值即可。
下面的问题就是如何构造这样的分割,我们可以使用二分查找
首先我们根据数组长度,进行第一个次尝试分割,第一次 我们选取第一个数组的一半进行分割,对于上面的例子,分割点就是 (0+5)/2 =2 第二个数组被分割的点就是 (数组一的长度 + 数组二的长度+1)/2 - 数组一的分割点= (5+5+1)/2 -2=3
所以以上数组被分为
array1= 1 , 3 | 8 , 9 ,11
array2 = 7 , 13 , 15 | 18, 19
检查一下 3<18 满足 ,15 >8 不满足条件
继续调整分割
很明显需要将数组一的分割线向右移,我们继续二分尝试 (2+5)/2=3 那么数组二的分割线为 11/2-3=2
分割后
array1= 1 , 3 ,8 | 9 ,11
array2 = 7 , 13 | 15 , 18, 19
检查 13>9 依然不满足 继续二分
这一次我们就找到了满意的分割,之后进行判断结果即可。
代码:
class Solution {
public double findMedianSortedArrays(int[] input1, int[] input2) {
if (input1.length > input2.length) {
return findMedianSortedArrays(input2, input1); // ensures 1st array is smaller than 2nd array
}
int x = input1.length;
int y = input2.length;
int low = 0;
int high = x;
while (low <= high) {
int partitionX = (low + high) / 2;
int partitionY = (x + y + 1) / 2 - partitionX;
int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1]; //如果左半边为空,把值设为最小,不影响后续的比较
int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX];
int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : input2[partitionY - 1];
int minRightY = (partitionY == y) ? Integer.MAX_VALUE : input2[partitionY];
if (maxLeftX <= minRightY && maxLeftY <= minRightX) {
if ((x + y) % 2 == 0) {
return ((double) Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2;
} else {
return (double) Math.max(maxLeftX, maxLeftY);
}
} else if (maxLeftX > minRightY) {
high = partitionX - 1;
} else {
low = partitionX + 1;
}
}
}
}
本文介绍了一种高效查找两个已排序数组合并后中位数的方法,采用二分搜索法实现,确保了时间复杂度为O(log(m+n))。通过实例演示了如何通过分割数组并比较边界元素来确定中位数。

被折叠的 条评论
为什么被折叠?



