【Leetcode】【BinarySearch】 4. Median of Two Sorted Arrays

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 be O(log (m+n)).

You may assume nums1 and nums2 cannot be both empty.

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 (m+n)),log时间复杂度想到用二分方法来做。

首先设两个数组分别长度为x,y,则中位数为第k个或k和k+1个的平均。

因此,目标是从nums1中取m1个,从nums2中取k-m1个。即用两个分区指针来分别对两个数组分区。

分区正确的条件是 nums1[partitionX-1] <= nums2[partitionY] && nums2[partitionY-1] <= nums1[partitionX]

若分区后,左边的均小于右边的,则分区正确,再从中取得中位数即可。

若分区不正确,如x的左边的最后一个大于了y的右边的第一个,则需要将x的分区左移,相应的y的分区会右移。反之则反移。

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        const int x = nums1.size();
        const int y = nums2.size();
        
        // 确保x长度小于y
        if (x > y)
            return findMedianSortedArrays(nums2, nums1);
        
        const int k = (x + y + 1) / 2;   // 总的数组的中位数的位置,即左边共k个,第k个为中位数
        
        int l = 0;
        int r = x;
        
        while (l <= r) {
            int partitionX = l + (r - l) / 2;
            int partitionY = k - partitionX;
            
            // 若partitionX == 0,说明X分区后左边没有元素了,用最小值;
            // 若partitionX == n,说明X分区后右边没有元素了,用最大值。确保后续的max和min的计算正确
            int maxLeftX = (partitionX == 0) ? INT_MIN : nums1[partitionX - 1];
            int minRightX = (partitionX == x) ? INT_MAX : nums1[partitionX];
            int maxLeftY = (partitionY == 0) ? INT_MIN : nums2[partitionY - 1];
            int minRightY = (partitionY == y) ? INT_MAX : nums2[partitionY];
            
            // 满足条件时
            if (maxLeftX <= minRightY && maxLeftY <= minRightX) {
                if ((x + y) % 2 == 0)   // 偶数时
                    return (max(maxLeftX, maxLeftY) + min(minRightX, minRightY)) * 0.5;
                else
                    return max(maxLeftX, maxLeftY);
            }
            
            // 不满足,进行调整
            else if (maxLeftX > minRightY)  // X的left部分取多了,更改x的分区
                r = partitionX - 1;
            else  // X的left取少了
                l = partitionX + 1;
        }
    }

讲解视频:https://www.youtube.com/watch?v=LPFhl65R7ww&frags=pl%2Cwn

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值