leetcode 4. Median of Two Sorted Arrays(Hard)

Problem :
There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example:
Example 1:
nums1 = [1, 3], nums2 = [2]
The median is 2.0

Example 2:
nums1 = [1, 2], nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5

Algorithm:
1、本题的时间复杂度是O(log (m+n)),根据时间复杂度我们很容易得出,我们每次要必须排除一半的元素,才能满足题目要求。因此,此题的思路与二分查找相似。
2、由于这题是另一类题目(找出两组序列中第K大的元素)的一种特殊情况,因此,在解题时,我把此题按照一般化的情况来求解,下面给出具体算法思路:
(1)保证A序列的长度小于B序列的长度,原因在下面说明;
(2)如果A序列长度为0,表明A中已经没有元素(因为步骤(1)的处理,所以必定A先变为0),这时第K大的元素即为B中的第K个元素;
(3)如果K = 1,表明所求元素即为A、B序列当前首部的最小值;
(4)若上面3条均不满足,我们令M1等于K/2与A序列长度的最小值,这样,我们就能保证:要么每次排除K/2个元素,使得总时间复杂度为O(log(K)),即题意的要求;要么排除掉A序列中所有元素,从而回到步骤(2)得出答案。注意,由于步骤(1)的处理,K - M1必然不会超过B序列的总长度;
(5)若A[BE1+M1-1] = B[BE2+M2-1],则其中任意一个即为所求答案,将其返回;
(6)若A[BE1+M1-1] < B[BE2+M2-1],则我们把A中这些较小的元素排除掉,因为它们肯定比K小(步骤(4))。这样我们只需要找两个新序列中第K-M1小的元素即可。根据步骤(4),我们排除了K/2(或A序列长度)个元素,满足时间复杂度要求;
(7)A[BE1+M1-1] > B[BE2+M2-1]的情况类似。

Code:

double find_kth_num(vector<int>& v1,int be1, int en1, vector<int>& v2, int be2, int en2, int k)
{
    int n1 = en1 - be1;
    int n2 = en2 - be2;
    if(n1 > n2) return find_kth_num(v2, be2, en2, v1, be1, en1, k);
    if(n1 == 0) return v2[be2 + k - 1];
    if(k == 1) return min(v1[be1],v2[be2]);

    int m1 = min(k / 2, n1), m2 = k - m1;

    if(v1[be1 + m1 - 1] == v2[be2 + m2 - 1]) return v1[be1 + m1 - 1];
    if(v1[be1 + m1 - 1] < v2[be2 + m2 - 1])
        return find_kth_num(v1, be1 + m1, en1, v2, be2, en2, k - m1);
    else
        return find_kth_num(v1, be1, en1, v2, be2 + m2, en2, k - m2);
}
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n1 = nums1.size();
        int n2 = nums2.size();
        if((n1 + n2) % 2)
            return find_kth_num(nums1, 0, n1, nums2, 0, n2, (n1 + n2) / 2 + 1); //第k个元素(k从1开始) 
        else
            return (find_kth_num(nums1, 0, n1, nums2, 0, n2, (n1 + n2) / 2) 
                    + find_kth_num(nums1, 0, n1, nums2, 0, n2, (n1 + n2) / 2 + 1)) / 2; 
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值