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