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

本文介绍了一种求解两个有序数组中位数的高效算法,时间复杂度为O(log(min(m,n)))。通过将数组分为左右两部分,确保左部分元素小于等于右部分,找到划分点即可计算中位数。

给定两个大小为 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

思路:
1.就是用外排法给两个有序数组排序,然后找出中位数,但是时间复杂度O(m+n),不满足题目要求
2.YouTube帮助理解的视频
这个外国小哥讲的很好,很清楚
大致思路是
将两个数组都分成两个部分
x1 x2 x3 x4 | x5 x6 x7
y1 y2 y3 | y4 y5 y6 y7
使得 左部分的元素数 和 右部分的元素数最多相差1
然后满足x4 <= y4 && y3 <= x5
其实这样就是把数画成了两堆,左堆的数全部<=右堆的数
那么
中位数就是(Max(x4,y3)+Min(x5,y4))/2
时间复杂度就是用来找这个划界的点O(log(min(m,n))),就是用二分查找,对长度最小的一个数组进行划界,那另外一个的界就可以算出来了

在这里插入图片描述

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if(nums1.length > nums2.length){
            int[] tmp = nums1;
            nums1 = nums2;
            nums2 = tmp;
        }
        int len1 = nums1.length;
        int len2 = nums2.length;
        int low = 0;
        int high = len1;
        while(low <= high){
            int partx = high + (low - high>>1);
            int party = ((len1+len2+1)>>1)-partx;
            
            int leftx = partx == 0?Integer.MIN_VALUE:nums1[partx-1];
            int lefty = party == 0?Integer.MIN_VALUE:nums2[party-1];

            int rightx = partx == len1?Integer.MAX_VALUE:nums1[partx];
            int righty = party == len2?Integer.MAX_VALUE:nums2[party];

            if(leftx <= righty && lefty <= rightx){
                if((len1+len2)%2 == 0){
                    //偶数情况下
                    return (double)(Math.max(leftx,lefty) + Math.min(rightx,righty))/2;
                }else
                    //奇数情况下
                    return (double)(Math.max(leftx,lefty));
            }else if(leftx > righty){
                high = partx - 1;
            }else if(lefty > rightx){
                low = partx + 1;
            }
        }
        return -1;
    }
}

位运算太容易出错了,be careful

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值