一、题目
给定两个大小为 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
示例3
nums1 = [1]
nums2 = [2, 3, 4, 5]
则中位数是 3.0
注:由于本题给的前两个示例看不出规律,我又新加了一个示例3,方便大家更准确的理解本题,本题是将两个数组合并,然后进行取中位数。
三、分析
本题是进行查找中位数,首先我们要清楚什么是中位数,中位数就是中间的位置的数值,如果是基数个的话正好就是 n / 2 + 1 位置的元素,如果是偶数的话就是中间两个元素的和除以2,也就是 n / 2 和 n / 2 + 1 两个元素的和除2。
四、实现
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int length1 = nums1.length;
int length2 = nums2.length;
int length = length1 + length2;
// 当前的元素值
int current = 0;
// 前一个元素值
int pre = 0;
// 数组1的下标
int index1 = 0;
// 数组2的下标
int index2 = 0;
// 由于只要找到第 n / 2 和 n / 2 + 1的元素,就可以将中位数早到,因此循环 n / 2 + 1次。
for (int i = 0; i <= length / 2; i++) {
pre = current;
// 这里由于两个数组都是有序的因此只要每次遍历的时候按照排序进行向下查找。
if (【index1 < length1 && (index2 == length2 || nums1[index1] < nums2[index2])】) {
current = nums1[index1++];
} else {
current = nums2[index2++];
}
}
if ((length & 1) == 0) {
return (pre + current) / 2.0;
}
return current;
}
}
本题最重要的是找到两个数组和在一起的新的数组的 n / 2 和 n / 2 + 1的元素,因此大家也可以直接将两个数组合在一起直接查找到中位数。 本题的核心在与如何在两个数组的下标的约束,以及当前的数值向前移动上。 我的解题思路是这样的,最开始我是这样判断的(index1 < length1 && nums1[index1] < nums2[index2])是true的时候进行 current = nums1[index1++]; 但是在运行的时候会发现如果数组2结束了,然后数组2还是小于数组1的值的时候会出现下标越界。因此判断条件需要加上 index2 == length2。当数组2结束的时候,直接遍历数组1就好了,由于遍历条件我们直接是一半的数组。所以遍历到最后的元素就是我们要的元素。