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

知识点


一、问题描述


二、算法思想

step1:默认数组A长度小于数组B的长度,合并之后的有序数组记作数组A+B,他的中位数在位置k
step2:由于数组AB都是有序数组,所以数组AB的中位数是A[k/2]和B[k/2];
step3:以k/2为界限将数组AB分别分割成数组A1A2和数组B1B2
step4:递归

  • A[k/2] < B[k/2]
    在A1中有k/2个元素小于A[k/2],在B1中有小于k/2个元素小于A[k/2],因此A+B中有小于k个元素小于A[k/2],此时删除A1的k/2个元素。
  • A[k/2] > B[k/2]
    同上,删除B1的k/2个元素
  • A[k/2] = B[k/2]
    中位数是A[k/2]

三、难点

递归实现


四、算法实现

代码如下:

class Solution {
public:
    int find(vector<int>& nums1,int i, vector<int>& nums2, int j, int k){
            //i和j是数组的第一个元素的下标 k是中位数的下标+1
            //默认nums1是较为短的A数组
            //cout << nums1.size() << ' ' << i << ' '<< nums2.size() << ' ' << j << ' '<< k << endl;
            if(nums1.size()- i > nums2.size() - j) return find(nums2,j , nums1, i , k);
            //边界:k==1 中位数下标==0  --->数组及其长度三种情况,A0B1 / A1B0 / A1B1  
            //又因A较短 只有两种情况 ---> A0B1 / A1B1
            if(k==1){
                if(nums1.size()==i) return nums2[j];
                else return min(nums1[i],nums2[j]); 
            }
            //边界2:A数组为空数组
            if(nums1.size() == i) return nums2[j + k - 1];
            //si和sj 是第k/2个元素的下一个位置


            int si =min((int)nums1.size(), i + k / 2) , sj = j + k - k / 2;
            if(nums1[si - 1] > nums2[sj - 1]) 
                return find(nums1,i,nums2,sj, k - (sj - j));
            else   
                return find(nums1,si,nums2,j, k - (si - i));

    }
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        //算法思想见笔记本  
        //nums1记作数组A nums2记住数组B 合并数组记A+B tot总数是A+B的元素总个数
        int tot  = nums1.size() + nums2.size();
        if( tot % 2 == 0){//偶数个数组,中位数是中间两数字left 和 right 的平均数
            int left = find(nums1,0 , nums2 , 0 , tot/2 );//nums1从0开始 nums2从0开始
            int right = find(nums1,0 ,nums2 , 0 , tot/2 + 1);
            return (left + right) / 2.0 ;
        }else{
            return find(nums1,0,nums2,0,tot/2 + 1);
        }         
    }
};
    

# 五、一题多解
# 六、链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值