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

题目描述

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0
示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

解题思路

总体上采用二分法,理论上当我们确定了一个数组的切分位置时,另一个数组的切分位置也随之确定,因此,为了减少操作次数,我们可以选择数组长度较小的数组进行操作。设置变量cut1用来指示nums1的切分位置,cut2用来指示nums2的切分位置,cutL和cutR用来表示cut1的切分范围。L1,R1用来指示cut1切分位置左右两边的值,L2,R2用来指示cut2切分位置左右两边的值。根据正常情况下L1应该小于R2,R1应该大于L2。我们可以根据这个来进行判断我们的切分位置是否正确。然后根据总的位数是否是偶数,奇数来进行相应的计算。

代码如下

package leetcode;

public class MedianofTwoSortedArrays {
    /**
     * There are two sorted arrays nums1 and nums2 of size m and n respectively
     * Find the median of the two sorted arrays. The overall run time complexity should by only O(log (m+n))
     *
     * Example 1:
     * nums1 = [1,3]
     * nums2 = [2]
     *
     * The median is 2.0
     * Example 2:
     * nums1 = [1,2]
     * nums2 = [3,4]
     *
     * The median is (2+3)/2 = 2.5
     *
     * 最优解时间复杂度:O(log min((m+n)) )
     *
     * num1: 3 5 8 9
     * num2: 1 2 7  10 11 12
     * @param nums1
     * @param nums2
     * @return
     */

    public double findMedianSortedArrays(int[] nums1,int[] nums2){
        // 知道一个数组的数量越少,可以节省操作次数,减少时间复杂度
        if(nums1.length > nums2.length){
            return findMedianSortedArrays(nums2,nums1);
        }
        int len = nums1.length + nums2.length;
        int cut1 = 0;
        int cut2 = 0;
        int cutL = 0; // 划分范围
        int cutR = nums1.length;
        while (cut1 <= nums1.length){
            cut1 = (cutR - cutL)/2 + cutL;
            cut2 = len/2 - cut1;
            double L1 = (cut1 == 0)?Integer.MIN_VALUE : nums1[cut1-1];
            double L2 = (cut2 == 0)?Integer.MIN_VALUE : nums2[cut2-1];
            double R1 = (cut1 == nums1.length)?Integer.MAX_VALUE : nums1[cut1];
            double R2 = (cut2 == nums2.length)?Integer.MAX_VALUE : nums2[cut2];
            if(L1 > R2){ // 当划分位置不正确时进行相应的移动
                cutR = cut1 - 1;
            }else if(L2 > R1){
                cutL = cut1 + 1;
            }else{
                if(len % 2 == 0){ // 根据奇偶来进行相应的计算
                    L1 = L1 > L2 ? L1:L2;
                    R1 = R1 < R2 ? R1:R2;
                    return (L1 + R1)/2;
                }else{
                    R1 = (R1 < R2) ? R1 : R2;
                    return R1;
                }
            }
        }
        return -1;
    }
}

运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值