【Hot100】LeetCode—4. 寻找两个正序数组的中位数


1- 思路

  • 1- 中位数的定义
    • 如果合并后的数组是 奇数位,中位数就是中间的数
    • 如果合并后的数组是 偶数位,中位数就是中间两个数的平均

递归法

① 问题抽象:

  • 将问题抽象成寻找两个数组中,第 k 大的数是多少即可解决这个问题,其中 k = (n+m)/2
  • 比较 A 数组,B 数组的 k/2 是多少

image.png
❗① 如果 A[k/2] < B[k/2],此时目标答案 k 的值,一定不在 A 的前 [k/2] 个元素中
image.png

  • 统计AB数组中 小于等于 A[k/2] 元素的个数有多少
    • A 中小于等于A[k/2] 元素的个数有 k/2个。
    • 在 B 中由于 B[k/2] > A[k/2],所以B中小于等于 A[k/2] 元素的个数小于 k/2 个。
  • 因此直接删除 A[0:k/2] 的元素

❗② 如果 A[k/2] > B[k/2],此时目标答案 k 的值,一定不在 B 的前 [k/2] 个元素中。
❗③ 如果 A[k/2] = B[k/2],此时目标答案 k 的值,就是 A[k/2] = B[2/k]

② 结论:

  • 每一次比较都可以删除 [k/2] 个元素
  • 当 k = 1 时候就可以找到最终结果,每次递归法 因此时间复杂度为 O(log k)

2- 实现

⭐4. 寻找两个正序数组的中位数——题解思路

在这里插入图片描述

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        // 1. 数据结构
        int len1 = nums1.length;
        int len2 = nums2.length;

        // 1.1 保证奇偶
        int left = (len1+len2+1)/2;
        int right = (len1+len2+2)/2;
        return((findK(nums1,0,len1-1,nums2,0,len2-1,left)+findK(nums1,0,len1-1,nums2,0,len2-1,right))*0.5);
    }


    public int findK(int[] nums1,int start1,int end1,int[] nums2,int start2,int end2,int k){
        // 1. 保持 1 最长
        int len1 = end1-start1+1;
        int len2 = end2-start2+1;
        if(len1>len2) return findK(nums2,start2,end2,nums1,start1,end1,k);

        // 终止条件
        if(len1==0) return nums2[start2+k-1];
        if(k == 1) return Math.min(nums1[start1],nums2[start2]);

        // 3.递归逻辑
        int i = start1 + (Math.min(len1,k/2)-1);
        int j = start2 + (Math.min(len2,k/2)-1);

        // 判断
        if(nums1[i]>nums2[j]){
            return findK(nums1,start1,end1,nums2,j+1,end2,k-(j-start2+1));
        }else{
            return findK(nums1,i+1,end1,nums2,start2,end2,k-(i-start1+1));
        }
    } 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值