leetcode4.寻找两个有序数组的中位数

  1. 题目:
    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
    请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
    你可以假设 nums1 和 nums2 不会同时为空。

  2. 示例:
    示例 1:
    nums1 = [1, 3]
    nums2 = [2]
    则中位数是 2.0
    示例 2:
    nums1 = [1, 2]
    nums2 = [3, 4]
    则中位数是 (2 + 3)/2 = 2.5

  3. 思路:
    a.归并排序思路,排序到第(n1+n2)/2个。时间复杂度O{(m+n)/2}
    b.二分搜索思想。
    log级别的肯定想到二分查找。
    按中位数的定义,问题求解变成:
    1.len(leftpart)==len(rightpart)
    2.max(leftpart)<=min(rightpart)
    3.median=(max(leftpart)+min(rightpart))/2.

  4. 代码:

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {     //采用归并排序思想,mergesort
        int n1=nums1.size(),n2=nums2.size();
        int stop=(n1+n2)/2;  //排序到0-(n1+n2)/2 
        int tmp1=0,tmp2=0;
        int i=0,j=0,k=0;
        //归并排序思路。tmp1,tmp2保存排好序的最后两位数
        while(i<n1&&j<n2&&k<=stop){
            if(nums1[i]<=nums2[j]){//num1中的数小,则将num1[i]归并
                tmp1=tmp2;
                tmp2=nums1[i];
                i++;k++;
            }
            else{//否则将num2[j]归并,
                tmp1=tmp2;
                tmp2=nums2[j];
                j++;k++;
            }
        }
        //其中一个数组已经归并完成,但还没到stop
        while(k<=stop&&i<n1){
            tmp1=tmp2;
            tmp2=nums1[i];
            i++;k++;
        }
        while(k<=stop&&j<n2){
            tmp1=tmp2;
            tmp2=nums2[j];
            j++;k++;
        }
        if((n1+n2)%2) return tmp2;  //奇数个,返回中间值
        else return (tmp1+tmp2)/2.0; //偶数个,返回平均中间值。
    }
};
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n1=nums1.size();
        int n2=nums2.size();
        if(n1>n2) //保证数组1一定最短
            return findMedianSortedArrays(nums2,nums1);
        int L1,L2,R1,R2,C1,C2,low=0,high=2*n1;
        while(low<=high){//二分
            C1=(low+high)/2;//C1是二分的结果。
            C2=n1+n2-C1;//关键点
            L1=(C1==0)?INT_MIN:nums1[(C1-1)/2];//nums1整体比中位数大,只能选L2
            R1=(C1==2*n1)?INT_MAX:nums1[C1/2];//nums1整体比中位数小,只能选R2
            L2=(C2==0)?INT_MIN:nums2[(C2-1)/2]; //num2整体比中位数大,只能选L1;
            R2=(C2==2*n2)?INT_MAX:nums2[C2/2];//nums2整体比中位数小,只能选R1
            if(L1>R2)//C1割太大,左移
                high=C1-1;
            else if(L2>R1)//C1割太小,右移
                low=C1+1;
            else //找到合适的分割,即在两个数组中,整个左部小于整个右部
                break;
        }
        return (max(L1,L2)+min(R1,R2))/2.0;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值