标签:
There are two sorted arrays A and B of size m and nrespectively. Find the median of the two sorted arrays.
Given A=[1,2,3,4,5,6]
and B=[2,3,4,5]
, the median is 3.5
.
Given A=[1,2,3]
and B=[4,5]
, the median is 3
.
The overall run time complexity should be O(log (m+n))
.
分析,先来复杂度高一点的:O(m + n).
分别用两个指针pa, pb指向两个array的第一个值,然后通过比较,不断移动pa或者pb的值,直到pa + pb + 1 = k.
1 class Solution { 2 /** 3 * @param A: An integer array. 4 * @param B: An integer array. 5 * @return: a double whose format is *.5 or *.0 6 * cnblogs.com/beiyeqingteng/ 7 */ 8 // O(m + n) approach 9 public double findMedianSortedArrays(int[] A, int[] B) { 10 int mid = (A.length + B.length) / 2; 11 int v1 = findKthSortedArrays(A, B, mid + 1); 12 if ((A.length + B.length) % 2 != 0) { 13 return v1; 14 } else { 15 int v2 = findKthSortedArrays(A, B, mid); 16 return (v1 + v2) / 2.0; 17 } 18 } 19 20 private int findKthSortedArrays(int[] A, int[] B, int k) { 21 if (A.length == 0) return B[k - 1]; 22 if (B.length == 0) return A[k - 1]; 23 24 if (k == 1) { 25 return Math.min(A[0], B[0]); 26 } else { 27 int pa = 0, pb = 0; 28 while (pa + pb + 1 < k) { 29 long va = getValue(A, pa); 30 long vb = getValue(B, pb); 31 32 if (va < vb) { 33 pa++; 34 } else { 35 pb++; 36 } 37 } 38 return (int)(Math.min(getValue(A, pa), getValue(B, pb))); 39 } 40 } 41 42 private long getValue(int[] arr, int p) { 43 // I used Long.MAX_VALUE to handle the case in which arr contains Integer.MAX_VALUE 44 return (p == arr.length ? Long.MAX_VALUE : arr[p]); 45 } 46 }
上面这个方法还可以改进,因为两个array都是排过序的,所以我们可以使用binary search来快查找。
其实下面这个解法是把问题转化成在两个排好序的数列中找出第一个最小的数。
如果A[i] <= B[j] (这里要确保 i + 1 + j + 1 = K), 那么我们可以肯定A[i]以及A[i]前面的数一定不可能是第K大的数(自己可以找几个例子试试)。那么我们可以在数组A中 i + 1 和 数组B中找第 k - i - 1 大的数,问题的规模是不是逐步缩小了?什么时候终止?就是当K = 1的时候,这个时候我们可以很容易找出第K(1)大的值。
1 public double findMedianSortedArrays(int[] A, int[] B) { 2 if ((A.length + B.length) % 2 == 1) 3 return findKth(A, B, 0, A.length - 1, 0, B.length - 1, (A.length + B.length) / 2 + 1); 4 else 5 return (findKth(A, B, 0, A.length - 1, 0, B.length - 1, (A.length + B.length) / 2) 6 + findKth(A, B, 0, A.length - 1, 0, B.length - 1, (A.length + B.length) / 2 + 1)) / 2.0; 7 } 8 9 // convert the question to find the first largest number 10 private int findKth(int A[], int B[], int i1, int i2, int j1, int j2, int k) { 11 int m = i2 - i1 + 1; 12 int n = j2 - j1 + 1; 13 14 // we need to switch because posB可能会超过B的size 15 if (m > n) return findKth(B, A, j1, j2, i1, i2, k); 16 if (m == 0) return B[j1 + k - 1]; 17 if (n == 0) return A[i1 + k - 1]; 18 if (k == 1) return Math.min(A[i1], B[j1]); 19 int posA = Math.min(k / 2, m); 20 int posB = k - posA; 21 if (A[i1 + posA - 1] <= B[j1 + posB - 1]) 22 return findKth(A, B, i1 + posA, i2, j1, j1 + posB - 1, k - posA); 23 else 24 return findKth(A, B, i1, i1 + posA - 1, j1 + posB, j2, k - posB); 25 }
Reference:
http://blog.csdn.net/linhuanmars/article/details/19905515
标签:
原文地址:http://www.cnblogs.com/beiyeqingteng/p/5634763.html