(1)4. 寻找两个有序数组的中位数(中)

https://leetcode-cn.com/problems/median-of-two-sorted-arrays/

给定两个大小为 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.首先,让我们在任一位置 i 将 A(长度为m) 划分成两个部分:
    *            leftA            |                rightA
    *   A[0],A[1],...      A[i-1] |  A[i],A[i+1],...A[m - 1]
    *
    * 由于A有m个元素,所以有m + 1中划分方式(i = 0 ~ m)
    *
    * 我们知道len(leftA) = i, len(rightA) = m - i;
    * 注意:当i = 0时,leftA是空集,而当i = m时,rightA为空集。
    *
    * 2.采用同样的方式,将B也划分为两部分:
    *            leftB            |                rightB
    *   B[0],B[1],...      B[j-1] |   B[j],B[j+1],...B[n - 1]
    *  我们知道len(leftA) = j, len(rightA) = n - j;
    *
    *  将leftA和leftB放入一个集合,将rightA和rightB放入一个集合。再把这两个集合分别命名为leftPart和rightPart。
    *
    *            leftPart         |                rightPart
    *   A[0],A[1],...      A[i-1] |  A[i],A[i+1],...A[m - 1]
    *   B[0],B[1],...      B[j-1] |  B[j],B[j+1],...B[n - 1]
    *
    *   如果我们可以确认:
    *   1.len(leftPart) = len(rightPart); =====> 该条件在m+n为奇数时,该推理不成立
    *   2.max(leftPart) <= min(rightPart);
    *
    *   median = (max(leftPart) + min(rightPart)) / 2;  目标结果
    *
    *   要确保这两个条件满足:
    *   1.i + j = m - i + n - j(或m - i + n - j + 1)  如果n >= m。只需要使i = 0 ~ m,j = (m+n+1)/2-i =====> 该条件在m+n为奇数/偶数时,该推理都成立
    *   2.B[j] >= A[i-1] 并且 A[i] >= B[j-1]
    *
    *   注意:
    *   1.临界条件:i=0,j=0,i=m,j=n。需要考虑
    *   2.为什么n >= m ? 由于0 <= i <= m且j = (m+n+1)/2-i,必须确保j不能为负数。
    *
    *   按照以下步骤进行二叉树搜索
    *   1.设imin = 0,imax = m,然后开始在[imin,imax]中进行搜索
    *   2.令i = (imin+imax) / 2, j = (m+n+1)/2-i
    *   3.现在我们有len(leftPart) = len(rightPart)。而我们只会遇到三种情况:
    *
    *      ①.B[j] >= A[i-1] 并且 A[i] >= B[j-1]  满足条件
    *      ②.B[j-1] > A[i]。此时应该把i增大。 即imin = i + 1;
    *      ③.A[i-1] > B[j]。此时应该把i减小。 即imax = i - 1;
    *
    * */

代码:

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m=nums1.length,n=nums2.length;
        if(m>n){
            int []tmp=nums1;nums1=nums2;nums2=tmp;
            int t=m;m=n;n=t;
        }
        int l=0,r=m,i,midNum=(m+n+1)/2;
        while(l<=r){
            i=(l+r)>>1;
            int j=midNum-i;
            if(i-1>=0&&j<n&&nums1[i-1]>nums2[j]){
                r=i-1;
            }else if(j-1>=0&&i<m&&nums2[j-1]>nums1[i]){
                l=i+1;
            }else {
                int mx,mn;
                if(i==0){
                    mx=nums2[j-1];
                }else if(j==0){
                    mx=nums1[i-1];
                }else 
                    mx=Math.max(nums1[i-1],nums2[j-1]);
                if((m+n)%2==1)
                    return mx;
                if(i==m){
                    mn=nums2[j];
                }else if(j==n){
                    mn=nums1[i];
                }else 
                    mn=Math.min(nums1[i],nums2[j]);
                return (mn+mx)*1.0/2;
            }
        }
        return 0;
    }
}

  

内容来源于网络如有侵权请私信删除