「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战」。
一、题目
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
示例 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
示例 3:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
示例 4:
输入:nums1 = [], nums2 = [1]
输出:1.00000
示例 5:
输入:nums1 = [2], nums2 = []
输出:2.00000
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?
二、我的解答
第一次解答
class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int num1Length;
int num2Length;
if (nums1==null){
num1Length=0;
}else {
num1Length= nums1.length;
}
if (nums2==null){
num2Length=0;
}else {
num2Length= nums2.length;
}
if((num1Length+num2Length)==0){
return 0;
}
int[] nums3=new int[num1Length+num2Length];
double median;
System.arraycopy(nums1,0,nums3,0,num1Length);
System.arraycopy(nums2,0,nums3,num1Length,num2Length);
for (int i=0;i<nums3.length-1;i++){
//第一趟会把最大的移到最后,比如4321,第一遍i=0,之后,就会变成3214,一共n个数,最多n-1趟就够了
for (int j=0;j<nums3.length-1;j++){
if (nums3[j]>nums3[j+1]){
int temp=nums3[j];
nums3[j]=nums3[j+1];
nums3[j+1]=temp;
}
}
}
int index=nums3.length/2;
if(nums3.length%2==0){
median=(nums3[index-1]+nums3[index])/2.0;
}else {
median=nums3[index];
}
return median;
}
}
思路及算法
简单粗暴,先将两个数组合并,然后冒泡排序。最后根据奇数,还是偶数,返回中位数。
但是这种暴力求解的方式,显然没有使用到题目给出的数组有序这一条件。其时间复杂度取决于所选的排序算法的时间复杂度。我这里使用的是冒泡排序,所以其算法复杂度应该为O((m+n)^2),这里的m和n分别为数组num1和num2的长度。其时间复杂度不符合题目时间复杂度限制为 O(log (m+n))的要求,所以我们的算法是错误的。
三、系统解答
方法一:有序数组的归并排序
使用归并的方式,合并两个有序数组,得到一个大的有序数组。大的有序数组的中间位置的元素,即为中位数。
这种方式其实是和我暴力求解方式是一样的,只不过,它利用了数组有序这个条件,借鉴归并排序的关键步骤【合并链各个有序数组】,将时间复杂度降到O(m+n)。在其过程中,不用完全合并,就能得到答案。
但这一步优化并不能改进算法的时间复杂度到O(log (m+n))
代码略
方法二:二分查找
中位数:在只有一个有序数组的时候,中位数把数组分割成两个部分
根据定义,分数组长度为奇数和偶数讨论。
数组长度为偶数时,中位数有两个,分割线两边,其中一个是左边数组的最大值,另一个是右边数组的最小值。
数组长度为基数时,中位数有1个,分割线在中位数的左边或者右边。
思路:只需要给出两个有序数组的一个恰当的分割线,中位数的值就由这个分割线的两侧的数决定。如何确定分割线的位置就可以使用二分查找法。
代码略
这部分听是听明白了,但是讲是不知道怎么讲。感兴趣的可以去官方网站查看视频讲解