4.给定两个大小为 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
这道题对于两个有序且不同为空的数组,首先先对其中一个为空的左判断,两个判断之后,如果总长度为偶数的话中位数就是由左中位数加右中位数之和除以2,为奇数就是直接返回右中位数,所以只要同时找到左中位数和右中位数就可以解了,而对两个排序的数组找到他们的中位数就可以用归并排序(我之前的博客有提到归并排序),代码如下:
//两个排序数组的中位数
public static double FindMedianSortedArrays(int[] nums1, int[] nums2)
{
int length1 = nums1.Length;
int length2 = nums2.Length;
if (length1 == 0) //对其中一个数组为空做判断
{
if ((length2 & 1)== 0) return 1.0 * (nums2[length2 / 2] + nums2[(length2 - 1) / 2]) / 2;
else {
return 1.0 * nums2[length2 / 2];
}
}
if (length2 == 0)
{
if ((length1 & 1) == 0) return 1.0 * (nums1[length1 / 2] + nums1[(length1 - 1) / 2]) / 2;
else
{
return 1.0 * nums1[length1 / 2];
}
}
int nums1Start = 0; //nums1索引
int nums2Start = 0; //nums2索引
int left = 0; //保存左中位数
int right = 0; //保存右中位数
for (int i = 0; i <= (length1 + length2) / 2; i++) {
left = right;
//同归并原理一样,对两个有序的数组进行排序;可以看我之前的归并排序博客
if (nums1Start < length1 && (nums2Start >= length2 || nums1[nums1Start] < nums2[nums2Start]))
{
right = nums1[nums1Start++];
}
else {
right = nums2[nums2Start++];
}
}
if (((length1 + length2) & 1) == 0) return 1.0 * (left + right) / 2;
else return 1.0 * right;
}