4. 寻找两个正序数组的中位数
Posted 我要出家当道士
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4. 寻找两个正序数组的中位数相关的知识,希望对你有一定的参考价值。
目录
1、Question
给定两个大小分别为
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
-10^6 <= nums1[i], nums2[i] <= 10^6来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2、Analysis
首先需要注意的是,两个数组都是有序的,可以通过不断的比较 num1[i] 与 num2[j] 来合并这两个数组。
另一个需要注意的是中位数的求法,如果是偶数的话,需要求中间两个的平均数;如果是奇数那么直接就是中间那个数。
官网提供的思路是转换为寻找第k个小数,通过二分法不断缩小搜索范围。具体讲下面的截图。
第一种思路是比较常见的,按位比较查找即可,时间复杂度为O(n);第二种思路时间复杂度为O(log n)。 但在实际提交运行过程中,第二种的运行时间较长,当然影响性能的因素有很多,这里不评论。
3、Code
第一种:
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int centI = (nums1Size + nums2Size) / 2;
int i = 0, j = 0, k = 0, cn = 1, tmp = 0;
double cents = 0;
if ((nums1Size + nums2Size) % 2 == 1) centI++;
if ((nums1Size + nums2Size) % 2 == 0) cn = 2;
int cnT = cn;
while(i < nums1Size || j < nums2Size)
{
if (!cnT) break;
if (j >= nums2Size || (i < nums1Size && nums1[i] < nums2[j]))
tmp = nums1[i++];
else
tmp = nums2[j++];
if (++k >= centI && cnT-- > 0) cents += tmp;
}
return cents / cn;
}
第二种:
int min(int x, int y)
{
return x > y? y : x;
}
int searchKMin(int* nums1, int nums1Size, int* nums2, int nums2Size, int k){
int i = 0, j = 0, half = 0;
while(i < nums1Size || j < nums2Size)
{
if ( i >= nums1Size ) return nums2[j + k - 1];
if ( j >= nums2Size ) return nums1[i + k - 1];
if ( k == 1) return min(nums1[i], nums2[j]);
half = k / 2;
int tmpI = min(i + half, nums1Size) - 1, tmpJ = min(j + half, nums2Size) - 1;
if (nums1[tmpI] <= nums2[tmpJ])
{
k -= (tmpI - i + 1);
i = tmpI + 1;
} else {
k -= (tmpJ - j + 1);
j = tmpJ + 1;
}
}
return 0;
}
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int len = nums1Size + nums2Size;
if (len % 2 == 1)
return searchKMin(nums1, nums1Size, nums2, nums2Size, len / 2 + 1);
else
return (searchKMin(nums1, nums1Size, nums2, nums2Size, len / 2) +
searchKMin(nums1, nums1Size, nums2, nums2Size, len / 2 + 1)) / 2.0;
}
4、Execution
第一种:
第二种:
以上是关于4. 寻找两个正序数组的中位数的主要内容,如果未能解决你的问题,请参考以下文章
Hard | LeetCode 4. 寻找两个正序数组的中位数 | 二分法
精选力扣500题 第67题 LeetCode 4. 寻找两个正序数组的中位数c++/java详细题解