package com.interview.algorithms.array; /** * Created_By: stefanie * Date: 14-11-10 * Time: 上午2:22 * * Solution: like "find k-th element in sorted array". * * 1. have lowA and lowB pointing to the begin of binarysearch area. * 2. if k == 1 return the min of A[lowA] and B[lowB] * 3. when k > 1, find the element offset is the k / 2 - 1 in A and B. * int keyA = lowA + half - 1 < A.length? A[lowA + half - 1] : Integer.MAX_VALUE; * int keyB = lowB + half - 1 < B.length? B[lowB + half - 1] : Integer.MAX_VALUE; * 4. if keyA > keyB, element smaller than k / 2 - 1 in A should smaller than the k-th element, should count in * so search (k - k / 2)th element start from lowA + k / 2 * otherwise sink B from lowB + k / 2; * 5. checking up bound (array.length) to avoid overstep the boundary * * Time: O(log(M + N)) */ public class C4_79_MedianTwoSortedArray { public static int median(int[] A, int[] B){ int length = A.length + B.length; if(length % 2 != 0) return findKth(A, 0, B, 0, length / 2 + 1); return (int)((findKth(A, 0, B, 0, length / 2) + findKth(A, 0, B, 0, length / 2 + 1)) / 2.0); } private static int findKth(int[] A, int lowA, int[] B, int lowB, int k){ if(lowA >= A.length) return B[lowB + k - 1]; if(lowB >= B.length) return A[lowA + k - 1]; if(k == 1) return Math.min(A[lowA], B[lowB]); int half = k / 2; int keyA = lowA + half - 1 < A.length? A[lowA + half - 1] : Integer.MAX_VALUE; int keyB = lowB + half - 1 < B.length? B[lowB + half - 1] : Integer.MAX_VALUE; if(keyA < keyB) return findKth(A, lowA + half, B, lowB, k - half); else return findKth(A, lowA, B, lowB + half, k - half); } }