Median of Two Sorted Arrays
https://leetcode.com/problems/median-of-two-sorted-arrays/
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
O(m+n), merge solution.
/** *There are two sorted arrays A and B of size m and n respectively. *Find the median of the two sorted arrays. *The overall run time complexity should be O(log (m+n)). */ public class Solution { public double findMedianSortedArrays(int A[], int B[]) { if(A.length==0&&B.length==0) return -1.0; if(A.length==0) { if(B.length%2==1){ return B[B.length/2]; } return 0.5*(B[B.length/2]+B[B.length/2-1]); } if(B.length==0){ if(A.length%2==1){ return A[A.length/2]; } return 0.5*(A[A.length/2]+A[A.length/2-1]); } int len=A.length+B.length; boolean isEven=false; int C[]=new int[len/2+1]; int a=0,b=0; for(int i=0;i<C.length;i++){ if(a>A.length-1){ C[i]=B[b]; b++; }else if(b>B.length-1){ C[i]=A[a]; a++; }else{ if(A[a]<B[b]){ C[i]=A[a]; a++; }else{ C[i]=B[b]; b++; } } } for(int i=0;i<C.length;i++){ System.out.print(C[i]); } System.out.println(); if(len%2==1) return C[C.length-1]; return 0.5*(C[C.length-1]+C[C.length-2]); } }O(log(m+n))
public class Solution { // using divide and conquer idea, each time find the mid of both arrays public double findMedianSortedArrays(int A[], int B[]){ return findMedianSortedArrays(A,A.length,B, B.length); } public double findMedianSortedArrays(int A[], int m, int B[], int n) { /* A[0, 1, 2, ..., n-1, n] */ /* A[0, 1, 2, ..., m-1, m] */ int k = (m + n + 1) / 2; double v = (double)FindKth(A, 0, m - 1, B, 0, n - 1, k); if ((m+n) % 2 == 0) { int k2 = k+1; double v2 = (double)FindKth(A, 0, m - 1, B, 0, n - 1, k2); v = (v + v2) / 2; } return v; } // find the kth element int the two sorted arrays // let us say: A[aMid] <= B[bMid], x: mid len of a, y: mid len of b, then wen can know // // (1) there will be at least (x + 1 + y) elements before bMid // (2) there will be at least (m - x - 1 + n - y) = m + n - (x + y +1) elements after aMid // therefore // if k <= x + y + 1, find the kth element in a and b, but unconsidering bMid and its suffix // if k > x + y + 1, find the k - (x + 1) th element in a and b, but unconsidering aMid and its prefix public int FindKth(int A[], int aL, int aR, int B[], int bL, int bR, int k) { if (aL > aR) return B[bL + k - 1]; if (bL > bR) return A[aL + k - 1]; int aMid = (aL + aR) / 2; int bMid = (bL + bR) / 2; if (A[aMid] <= B[bMid]) { if (k <= (aMid - aL) + (bMid - bL) + 1) return FindKth(A, aL, aR, B, bL, bMid - 1, k); else return FindKth(A, aMid + 1, aR, B, bL, bR, k - (aMid - aL) - 1); } else { // A[aMid] > B[bMid] if (k <= (aMid - aL) + (bMid - bL) + 1) return FindKth(A, aL, aMid - 1, B, bL, bR, k); else return FindKth(A, aL, aR, B, bMid + 1, bR, k - (bMid - bL) - 1); } } }
both of two solution are super slow.
One possible solution is a variant of binary search. The idea is.
m=A.length, n=B.length, m>n. Find the median of A, which is at m/2. And get the number in B that smaller than A(m/2) by binary search. The outer loop is o(log(m)), the inner loop is O(log(n)), the whole solution is O(log(m+n)). Here is