【刷题记录】4. 寻找两个正序数组的中位数
一、题目描述
来源:力扣(LeetCode)
给定两个大小分别为 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
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
二、思考分析
1 简单暴力-合并数组求解中位数
直接合并两个有序数组,得到一个数组。然后直接得到中位数即可。这个可能是我们第一时间想到的方法。不考虑时间复杂度的话。
这种方法的时间复杂度为 不满足题目的要求
2. 二分法
对于一个正序的数组,查找数组的中位数,实质上就是寻找数组中第 X 小的数组(X 就是中位数位于数组中的第几位),所以我们可以把这个问题转换为寻找第 X 个数。
对于两个正序数组来说,就是寻找两个数组中第 2/X 小的数组
然后比较两个数组的第 2/X 个数的大小
如果 第一个数组 num1 的第 2/X 个数字小于于第二个数字的 那么说明 num1 的前 2/X 个数组中不存在我们最终需要找的整体第 X/2 小的值 ,可以排除这些数
因为排除的数组肯定位于中位数前面 然后在排除之外的两个新数组 X-排除的数 小的即可
为了防止数组长度小于 X/2,所以每次比较 min(X/2,len(数组) 对应的数字,把小的那个对应的数组的数字排除,将两个新数组进入递归,并且 X 要减去排除的数字的个数。递归出口就是当 X=1 或者其中一个数字长度是 0 了。
三、代码实现
复杂度分析
时间复杂度
运行结果
总结
多思考问题的本质,然后将问题转为我们我们熟悉的思想。
版权声明: 本文为 InfoQ 作者【WangNing】的原创文章。
原文链接:【http://xie.infoq.cn/article/2c1f3dc1271b75125154df140】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论