Leetcode–4. 寻找两个正序数组的中位数(二分法) [2020.9.7]
前言
这题卡了好一会儿,主要还是细节的处理不够,以及做题的经验不足。
首先,题目要求算法的时间复杂度是0(log(m+n)),所以先排除将两个向量合并成一个向量的想法,然后求中位数的方法,时间复杂度为O(n)。一开始我的想法是构造一个最大堆,然后求第k大的数,但是发现其时间复杂度为O(nlogn),所以这条路也不通。
然后就想到了二分的角度去解决问题,显然二分的方法时间复杂度为0(log(n))级别,但一个难点在于如何运用二分的方法。我们知道中位数的定义,即:顺序排列的一组数据中居于中间位置的数,也就是两个向量合并成一个顺序的长向量的中间那个数。我们是否能够利用中位数这一已知信息作为二分法的切入口呢?
我们易知两个数组A、B正序排列,我们假设所求中位数为k,即求两数组合并后中第k小的数。我们可以分别取A、B第k/2的数a,b,两者进行比较。若a<b,那我们可以肯定的是a和a之前的数都不可能是第k小的数(a最大值只可能为k-1大),将其排除。
排除后的变化,a数组的头变成第[k/2]+1个数,k的值变为k/2(注意,准确来说应该是减去排除A组元素个数,不一定是k/2).然后依次类推,直到k的值变为1取A、B两个数组头元素较小即可。或者某个数组为空,这为另外一个数组对应位置的元素(代码有展现)。
需要注意的情况是一些特殊情况:
- 若A数组的个数小于k/2,那么就直接取A数组的尾元素(此时排除的个数不为k/2)
- A、B元素个数和为奇偶数,我们可以将其统一
- k的值为1,直接比较A、B两个数组头,取较小。
代码的编写使用了递归的方法,细节请查看代码
题目
代码
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.