问题描述:

两个排序的数组A和B分别含有m和n个数,找到两个排序数组的中位数,要求时间复杂度应为O(log (m+n))。转化成找到两个数组的第K大数字进行解决

解题方法:

  对于一个长度为n的已排序数列a,若n为奇数,中位数为a[n / 2 + 1] , 若n为偶数,则中位数(a[n / 2] + a[n / 2 + 1]) / 2如果我们可以在两个数列中求出第K小的元素,便可以解决该问题不妨设数列A元素个数为n,数列B元素个数为m,各自升序排序,求第k小元素取A[k / 2] B[k / 2] 比较,如果 A[k / 2] > B[k / 2] 那么,所求的元素必然不在B的前k / 2个元素中(证明反证法)反之,必然不在A的前k / 2个元素中,于是我们可以将A或B数列的前k / 2元素删去,求剩下两个数列的k - k / 2小元素,于是得到了数据规模变小的同类问题,递归解决如果 k / 2 大于某数列个数,所求元素必然不在另一数列的前k / 2个元素中,同上操作就好。

  递归过程中的边界条件:

  1、当两个数组中其中有一个为空,直接返回另外一个的第K个元素

    什么时候会出现空,当有一个数组的有效比较长度恰好是K/2个,并且这个位置的元素小于另外一个数组的元素,该数组的有效比较区间发生改变,这个时候会发生一个为空一个不为空的情况,当然也可以在初始时就进行判断。

  2、当k == 1时,返回两个数组起始位置的较小值

  另外,在递归取每个数组的第K/2大的元素时,可能数组中A的元素已经不够了,这个时候两个元素的diK大必然在A和另外一个数组的后K/2的位置里,此时可以将A的比较元素设置成为无穷大,保证将另外的数组的前K/2个元素删去。

有序数组寻找中位数以及寻找K大元素

当其中一个数组中的元素不够K/2时,设其长度为L2,那么L2 + L1(其实就是K/2) < K必然成立,那么对于上面的数组来说寻找的第K大就不可能在前面的L1中,必然在两个黑色的部分中,此时将上面的数组的前K/2个元素去除即可;

  

//看做是找到两个序列的第K大个数的问题,如果是奇数个数字那么就是找到一个,
//如果是偶数,那么就找找K个和K+1个数字
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int totalLength = nums1.size() + nums2.size();
        double res;
        if(totalLength & 1){
            res = findKth(nums1, 0, nums2, 0, totalLength/2 + 1); 
        }else{
            double temp1 = findKth(nums1, 0, nums2, 0, totalLength/2);
            double temp2 = findKth(nums1, 0, nums2, 0, totalLength/2 + 1);
            res = (temp1 + temp2) / 2.0;
        }
        return res;
    }
    
    double findKth(vector<int>& nums1, int start1, vector<int>& nums2, int start2, int index){
        if(start1 >= nums1.size()){
            return (double)nums2[start2 + index - 1];
        }
        if(start2 >= nums2.size()){
            return (double)nums1[start1 + index - 1];
        }
        if(index == 1){
            return min(nums1[start1], nums2[start2]);
        }
        int nums1_key = start1 + index / 2 - 1 >= nums1.size()? INT_MAX : nums1[start1 + index / 2 - 1];
        int nums2_key = start2 + index / 2 - 1 >= nums2.size()? INT_MAX : nums2[start2 + index / 2 - 1];
        if(nums1_key < nums2_key){
            return findKth(nums1, start1 + index / 2, nums2, start2, index - index / 2);
        }else{
            return findKth(nums1, start1, nums2, start2 + index / 2, index - index / 2);
        }
    }
};
find Kth and find midian

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-11-11
猜你喜欢
  • 2021-10-05
  • 2022-03-08
  • 2022-12-23
  • 2022-12-23
  • 2022-02-18
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案