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

题目

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。

示例:
在这里插入图片描述

思路

根据中位数的定义,当 m+n 是奇数时,中位数是两个有序数组中的第 (m+n)/2 个元素,当 m+n 是偶数时,中位数是两个有序数组中的第 (m+n)/2个元素和第 (m+n)/2+1 个元素的平均值。因此,这道题可以转化成寻找两个有序数组中的第 k 小的数,其中 k 为 (m+n)/2或 (m+n)/2+1。

在这里插入图片描述

代码

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len1 = nums1.length;
        int len2 = nums2.length;
        int totalLen = len1 + len2;
        //奇数,中位数是两个有序数组中的第 (m+n)/2 个元素
        if(totalLen % 2 == 1){
            double median = getKthElement(nums1,nums2,totalLen/2+1);
            return median;
        }else{
            //偶数时,中位数是两个有序数组中的第 (m+n)/2个元素和第 (m+n)/2+1 个元素的平均值
            double median = (getKthElement(nums1,nums2,totalLen/2) + getKthElement(nums1,nums2,totalLen/2 + 1)) / 2.0;
            return median;
        }

    }

    public int getKthElement(int[] nums1,int[] nums2,int k){
        int len1 = nums1.length;
        int len2 = nums2.length;
        int index1 = 0, index2 = 0;
        while(true){
            if(index1 == len1){
                return nums2[index2+k-1];
            }
            if(index2 == len2){
                return nums1[index1+k-1];
            }
            //我们要找第 1 小的数字,所以只需判断两个数组中第一个数字哪个小就可以了
            if(k==1){
                return Math.min(nums1[index1],nums2[index2]);
            }

            int half = k / 2;
            //删除" 了一些元素(这些元素都比第 k 小的元素要小)更新index的值
            //如果超过数组的长度,就指向数组的末尾
            int newIndex1 = Math.min(index1 + half,len1) - 1;
            int newIndex2 = Math.min(index2 + half,len2) - 1;
            if(nums1[newIndex1] <= nums2[newIndex2]){
                k -= (newIndex1-index1+1);
                index1 = newIndex1 + 1;
            }else{
                k -= (newIndex2-index2+1);
                index2 = newIndex2 + 1;
            }

        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值