leetcode——二分

(1)4. 尋找兩個有序數組的中位數(中)

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

給定兩個大小爲 m 和 n 的有序數組 nums1 和 nums2。java

請你找出這兩個有序數組的中位數,而且要求算法的時間複雜度爲 O(log(m + n))。算法

你能夠假設 nums1 和 nums2 不會同時爲空。數組

示例 1:spa

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

則中位數是 2.0
示例 2:blog

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

則中位數是 (2 + 3)/2 = 2.5get

思路:思路不是很難,但要注意不少邊界狀況,詳情參考下面別人的註釋:it

    /*
    * 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;
    }
}
相關文章
相關標籤/搜索