题干
给定两个大小分别为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
题解
(一)归并排序法
时间复杂度 空间复杂度
思路及算法
寻找中位数的小TIPS
假设两个有序数组的长度分别是m和n,由于两个数组长度之和m+n的奇偶性不确定,但是只要分别找第 (m+n+1)/2 个和第 (m+n+2)/2 个的值,然后求这两者的平均值即可。这对奇偶数均适用。
用归并排序法将两个数组合并成一个有序数组,然后寻找中位数。
代码实现
public double findMedianSortedArrays(int[] nums1,int[] nums2){
int nums[]; //创建新数组
int m = nums1.length; //nums1数组长度
int n = nums2.length; //nums2数组长度
nums = new int[m + n]; //给新nums数组分配空间
//开始考虑边界情况:其中一个为空数组
if (m == 0){ //nums1数组为空
return (nums2[(n+1)/2-1] + nums2[(n+2)/2-1]) / 2.0;
} //注意,下标从0开始,故nums2的索引要减一;为了保证结果是浮点数,所以要除以2.0
if (n == 0){ //nusm2数组为空
return (nums1[(m+1)/2-1] + nums1[(m+2)/2-1]) / 2.0;
}
int count = 0; //nums数组的下标索引
int i = 0; //控制nums1数组下标
int j = 0; //控制nums2数组下标
//一般情况
while ( count != (m + n)){
if (i == m){
while (j != n){
nums[count++] = nums2[j++];
} break;
} //当nums1到尽头,但是nums2没到尽头的时候
if (j == n){
while (i != m){
nums[count++] = nums1[i++];
} break;
} //当nums2到尽头,但是nums1没到尽头的时候
if ( nums1[i] < nums2[j]){
nums[count++] = nums1[i++];
} else{
nums[count++] = nums2[j++];
}
}
return (nums[(count+1)/2-1] + nums[(count+2)/2-1]) / 2.0;
}
反思与总结
- 一定要细心!!!经常出现一些小错:数组搞混、没写自加、数组索引忘记减一
- 边界情况要考虑清除且完整
(二)二分法
下次再写