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