• leetcode——二分


    (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;
        }
    }
    

      

  • 相关阅读:
    安装pip-9.0.1-py2.py3-none-any.whl
    Flask-Moment本地化日期和时间
    在windows下使用VirtualEnv建立flask项目
    java web中Jdbc访问数据库步骤通俗解释(吃饭),与MVC的通俗解释(做饭)
    java web中cookie的永久创建与撤销
    myeclipse与数据库进行连接(无需写代码进行验证)
    求二维数组最大子数组和
    Java代码实现 增删查 + 分页——实习第四天
    JDBC 数据库连接操作——实习第三天
    Java基础语法实例(2)——实习第二天
  • 原文地址:https://www.cnblogs.com/mcq1999/p/12075630.html
Copyright © 2020-2023  润新知