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

首先,根据题目中复杂度为O(log(m+n)),应该是用二分法。刚开始觉得很有想法,应该用分治,就是写不出来,无奈又走上了搜题解的不归路(题解也看了好久好久啊)

怎么用这个二分法呢

两个数组nums1和nums2,不同时为空。i为数组nums1的起始位置,j为数组nums2的起始位置,k表示查找两个数组的第k个元素。运算中一步步缩小要查找元素的范围,用递归来实现,跳出递归的途径有两个:

1、若i>nums1的长度,说明nums1中的所有数字都被淘汰,此时要找的第k个数就是数组nums2的第k个数;j>nums2同理

2、若k=1,则返回两个有序数组起始元素的最小值,即min(nums[1],nums[2])

递归过程:

两个数组长度分别为m和n,总长度为m+n,中位数是第(m+n+1)/2 个数和第 (m+n+2)/2 个数的平均值(奇偶都是如此),所以求中位数的问题就转化为了找第(m+n+1)/2和第(m+n+2)/2个数的问题,即上面所说第k个数

这里,二分的并不是数组,而是k。分别在nums1和nums2中找第k/2个数,若nums1[k/2-1]<nums2[k/2-1],即可淘汰nums1的前k/2个数,同时k要减去k/2。

例如

nums1=[1,2,3],nums2=[2,4,5],要找这两个有序数组的第4个元素,则找到

nums1[k/2-1]=nums1[1]=2,

nums2[k/2-1]=nums2[1]=4,    

2<4,则nums1数组第2个元素及其左边的元素均小于nums2的第2个元素,将nums1前两个元素淘汰。同时原先要找的第4个元素,已经变成要找第4-2,即淘汰nums1前两个元素以后的所有元素中的第2个。

继续进行此操作

直到跳出递归结构

 

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int m=nums1.size(),n=nums2.size();
        int i=0,j=0;
        return (findK(nums1,i,nums2,j,(m+n+1)/2)+findK(nums1,i,nums2,j,(m+n+2)/2))/2.0;
        
    }
    int findK(vector<int>& nums1,int i,vector<int>& nums2,int j,int k){
            if (i>=nums1.size()){
                return nums2[j+k-1];
            }
            else if(j>=nums2.size()){
                return nums1[i+k-1];
            }
            if(k==1){
                return min(nums1[i],nums2[j]);
            }
            int Vk1=(i+k/2-1<nums1.size())?nums1[i+k/2-1]:INT_MAX;
            int Vk2=(j+k/2-1<nums2.size())?nums2[j+k/2-1]:INT_MAX;
            if (Vk1<Vk2){
                return findK(nums1,i+k/2,nums2,j,k-k/2);  //淘汰nums1的前k/2个元素
            }
            else{
                return findK(nums1,i,nums2,j+k/2,k-k/2);
            }
            
        }
};

k=k/2和k=k-k/2是不一样的………………粗心了

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值