LeetCode 4 - Median of Two Sorted Arrays

一、问题描述

Description:

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)).

有两个有序的数组 nums1 和 nums2,大小分别为 mn。找出这两个有序数组的中位数,要求时间复杂度为O(log(m+n))


二、解题报告

解法一:暴力法

题目要求里写了要求时间复杂度为O(log(m+n)),然而直接暴力解决(时间复杂度O(m+n))也能够AC,我不知道为什么。

所谓暴力法,就是直接合并两个有序数组,然后返回合并后的数组的中位数。

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
    vector<int> nums;
    int M = nums1.size();
    int N = nums2.size();
    int i=0, j=0;
    while(i<M && j<N)
    {
        if(nums1[i] < nums2[j])
            nums.push_back(nums1[i++]);
        else
            nums.push_back(nums2[j++]);
    }

    while(i<M)
        nums.push_back(nums1[i++]);
    while(j<N)
        nums.push_back(nums2[j++]);

    if((M+N)%2 == 0)  // 偶数
        return (nums[(M+N)/2]+nums[(M+N)/2-1])/2.0;
    else
        return nums[(M+N)/2];
}

解法二:分治法

采用分治法的思想是求两个有序数组的第 k 小数,而中位数就是第 m+n2 小的数。

假设数组A和B的元素个数都大于k2,我们比较 A[k21]B[k21] 两个元素,这两个元素分别表示A的第 k2 小的元素和B的第 k2 小的元素。这两个元素比较共有三种情况:>、<和=。

  1. A[k21]<B[k21] ,这表示A[0]~A[k21]的元素都在A和B合并之后的前k小的元素中。换句话说,我们要在剩下的元素里找 kk2 小的元素。

  2. A[k21]>B[k21]时存在类似的结论。

  3. A[k21]=B[k21]时,我们已经找到了第k小的数,就是这个相等的元素。

通过上面的分析,我们可以采用递归的方式实现寻找第k小的数。另外需要考虑几个边界条件:

  • 如果 A 或者 B 为空,则直接返回B[k1]或者A[k1]
  • 如果k为1,我们只需要返回A[0]和B[0]中的较小值
  • 如果 A[k21]=B[k21],返回其中一个

函数实现如下:

int findKth(int A[], int m, int B[], int n, int k)  
{  
    if (m > n)    // 保证数组A的大小总是小于数组B的大小
        return findKth(B, n, A, m, k);  
    if (m == 0)   // 如果A为空
        return B[k - 1];  
    if (k == 1)   // 如果k为1
        return min(A[0], B[0]);  

    // 每次把k分两半
    int pa = min(k/2, m);  /*A的元素可能小于k/2个*/
    int pb = k - pa;

    if (A[pa-1] < B[pb-1])  
        return findKth(A+pa, m-pa, B, n, k-pa);  

    else if (A[pa-1] > B[pb-1])  
        return findKth(A, m, B+pb, n-pb, k-pb);  
    else  
        return A[pa-1];  
}


下面是 Solution:

class Solution {
public:
    int findKth(int A[], int m, int B[], int n, int k)  
    {  
        if (m > n)    // 保证数组A的大小总是小于数组B的大小
            return findKth(B, n, A, m, k);  
        if (m == 0)   // 如果A为空
            return B[k - 1];  
        if (k == 1)   // 如果k为1
            return min(A[0], B[0]);  

        // 每次把k分两半
        int pa = min(k/2, m);  /*A的元素可能小于k/2个*/
        int pb = k - pa;

        if (A[pa-1] < B[pb-1])  
            return findKth(A+pa, m-pa, B, n, k-pa);  

        else if (A[pa-1] > B[pb-1])  
            return findKth(A, m, B+pb, n-pb, k-pb);  
        else  
            return A[pa-1];  
    } 

     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int *A = nums1.data();
        int *B = nums2.data();
        int m = nums1.size();
        int n = nums2.size();

        int total = m+n;
        if (total%2 == 1)  // 奇数个
            return findKth(A, m, B, n, total/2+1);  
        else  
            return (findKth(A, m, B, n, total/2) 
                    + findKth(A, m, B, n, total/2+1)) / 2.0; 
     }
};





LeetCode答案源代码:https://github.com/SongLee24/LeetCode


转载于:https://www.cnblogs.com/songlee/p/5738067.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值