题目描述
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
提示:
- nums1.length == m
- nums2.length == n
- 0 <= m <= 1000
- 0 <= n <= 1000
- 1 <= m + n <= 2000
- -106 <= nums1[i], nums2[i] <= 106
题解思路
基本情况
设置一个n变量用于记录已经遍历的元素个数,设置i,j变量用于记录两个数组下一次需要遍历的元素。
判断nums1[i]与nums2[j]的大小关系,小的那个数组下标进一,并将n自增。
重复上述操作直到n自增到中位数所在的位置,最后输出中位数的值。
特殊情况
某一个数组已经遍历完了,但n还没有到达中位数所在的位置,就不需要判断nums1[i]与nums2[j]的大小关系了,只需要将未遍历完的数组继续遍历即可。
题解代码
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int lengthSum = nums1.length + nums2.length;
if(lengthSum%2 == 0){
int stop = lengthSum/2;
int i = 0,j = 0;//i用于记录第一个数组下一次该遍历哪一个,j用于记录第二个数组下一次遍历哪一个
int n = 0;//n用于记录已经遍历的元素个数
double mid = 0;
while(n<stop-1){
if(i==nums1.length){
n++;
j++;
}
else if(j==nums2.length){
n++;
i++;
}
else if(nums1[i]<nums2[j]){
n++;
i++;
}
else{
n++;
j++;
}
}
if(i==nums1.length){
mid += nums2[j];
j++;
}
else if(j==nums2.length){
mid += nums1[i];
i++;
}
else if(nums1[i]<nums2[j]){
mid += nums1[i];
i++;
}
else{
mid += nums2[j];
j++;
}
if(i==nums1.length){
mid += nums2[j];
}
else if(j==nums2.length){
mid += nums1[i];
}
else if(nums1[i]<nums2[j]){
mid += nums1[i];
}
else{
mid += nums2[j];
}
return mid/2;
}
else{
int stop = (lengthSum+1)/2;
int i = 0,j = 0;//i用于记录第一个数组下一次该遍历哪一个,j用于记录第二个数组下一次遍历哪一个
int n = 0;//n用于记录已经遍历的元素个数
double mid = 0;
while(n<stop-1){
if(i==nums1.length){
n++;
j++;
}
else if(j==nums2.length){
n++;
i++;
}
else if(nums1[i]<nums2[j]){
n++;
i++;
}
else{
n++;
j++;
}
}
if(i==nums1.length){
mid = nums2[j];
}
else if(j==nums2.length){
mid = nums1[i];
}
else if(nums1[i]<nums2[j]){
mid = nums1[i];
}
else{
mid = nums2[j];
}
return mid;
}
}
}
优化思路
直接开辟一个新的数组,将两个数组合并成一个新的有序数组之后再计算中位数,思路更清晰,实现更简便。