[LeetCode]004-Median of Two Sorted Arrays

该博客探讨了如何在O(log(m+n))的时间复杂度内找到两个已排序数组的中位数。提供了两种解决方案,一种是简单地合并数组,另一种利用二分查找法寻找第k小的元素,其中k为数组总长度的一半,对于偶数长度的数组,取中间两个数的平均值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:
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)).

Solutions(1):
//简单的,直接合并两个有序数组(类似归并排序),找出中间值即可。
复杂度应该为O(n+m),但也通过了LeetCode测试。

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
         int i =0;
        int j =0;
        int k =0;
        int n1 = nums1.size();
        int n2 = nums2.size();
        int* merge_array = new int[n1+n2];
        double median = 0.0;
        while(i<n1 && j < n2)
        {
            if(nums1[i] < nums2[j])
            {
                merge_array[k++] = nums1[i++]; 
            }
            else
            {
                merge_array[k++] = nums2[j++];
            }
        }

        while(i < n1)
        {
            merge_array[k++] = nums1[i++]; 
        }
        while(j<n2)
        {
            merge_array[k++] = nums2[j++];
        }
        if(k == 0)
        {
            return 0;
        }
        if(k %2 == 0)
        {
            median = (merge_array[k/2] + merge_array[k/2 - 1])/2.0; 
        }
        else
        {
            median = merge_array[k/2];
        }
        delete[] merge_array;
        return median;
    }

Solution(2):
思路,转化为求第k大小数字,这里k其实就是m+n/2,奇数则直接中值大小,偶数则m+n/2和m+n/2+1两个数平均。

关于如何求两个有序数组a、b合并的第k大小数字,二分原理,假设各存在k/2个,则只需比较a[k/2]和b[k/2]。
(1)a[k/2] < b[k/2] -> a中的前k/2数字在总体的k位置之前,故扔掉,继续比较剩下的a数组和原有b数组中合并后的第k-k/2个大小的数字。
(2)a[k/2] > b[k/2] 同上
(3)相等,则任意返回一个即可

代码表示的更加清晰,如下:

//只要查找当前的第k个数即可,
double findkey(int a[],int m,int b[],int n,int k)
{
    if(m > n) //使得第一个数组长度一直小于第二个长度
    {
        return findkey(b,n,a,m,k);
    }
    if(m == 0)//此时层层递减后,a数组已经没有排在k前的数字了
    {
        return b[k-1];
    }
    if(k ==1) //表示层层递减,只需找到当前组合的第一个点时
    {
        return min(a[0],b[0]);
    }

    int pa = min(m,k/2); 
    int pb = k - pa;
    if(a[pa-1] > b[pb-1])
    {
        return findkey(a,m,b+pb,n-pb,k-pb);
    }
    else if(a[pa-1] < b[pb-1])
    {
        return findkey(a+pa,m-pa,b,n,k-pa);
    }
    else
        return a[pa-1];
}
 double findMedianSortedArrays(int nums1[],int n1, int nums2[],int n2) {
         int total = n1+n2;
         if(total & 0x1)
         {
             return findkey(nums1,n1,nums2,n2,total/2+1);
         }
         else
         {
             return (findkey(nums1,n1,nums2,n2,total/2) + findkey(nums1,n1,nums2,n2,total/2 +1)) /2;
         }
     }

参考:http://blog.youkuaiyun.com/yutianzuijin/article/details/11499917/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值