|
| 1 | +/* |
| 2 | + * Author : Feng Wei |
| 3 | + * Date : Nov 15, 2014 |
| 4 | + * |
| 5 | + * There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. |
| 6 | + * |
| 7 | + * The overall run time complexity should be O(log (m+n)). |
| 8 | + */ |
| 9 | + |
| 10 | +#include <iostream> |
| 11 | +#include <algorithm> |
| 12 | +using namespace std; |
| 13 | + |
| 14 | +/* |
| 15 | + * we are required to find the median of array, |
| 16 | + * |
| 17 | + * if array.len is odd { |
| 18 | + * return array[(len + 1) / 2 ]; |
| 19 | + * } |
| 20 | + * else { |
| 21 | + * return (array[len / 2] + array[len / 2 + 1]) / 2; |
| 22 | + * } |
| 23 | + * note: len = m + n |
| 24 | + */ |
| 25 | +class Solution { |
| 26 | +public: |
| 27 | + /* |
| 28 | + * the problem can be transformed to find the kth smallest number in two arrays, |
| 29 | + * |
| 30 | + * Supposed that two arrays A and B, A.size() > k / 2 and B.size() > k / 2: |
| 31 | + * |
| 32 | + * 1. if A[k / 2 - 1] < B[k / 2 - 1], it means that A[0] ~ A[k / 2 - 1] in the top k of the array merged A and B; |
| 33 | + * 2. if A[k / 2 - 1] > B[k / 2 - 1], this sitution is similar to 1; |
| 34 | + * 3. if A[k / 2 - 1] = B[k / 2 - 1], return A[k / 2 - 1] or B[k / 2 - 1]. |
| 35 | + * |
| 36 | + * but we must consider some edge cases: |
| 37 | + * |
| 38 | + * 1. if A or B is empty, return B[k - 1] or A[k - 1]; |
| 39 | + * 2. if k == 1, return min(A[0], B[0]); |
| 40 | + * 3. if A[k / 2 - 1] == B[k / 2 - 1], return one of them. |
| 41 | + */ |
| 42 | + |
| 43 | + double findMedianSortedArrays(int A[], int m, int B[], int n) { |
| 44 | + int len = m + n; |
| 45 | + double result; |
| 46 | + |
| 47 | + if ((len & 1) != 0) { |
| 48 | + return findKNum(A, m, B, n, len / 2 + 1); |
| 49 | + } |
| 50 | + else { |
| 51 | + double a = findKNum(A, m, B, n, len / 2); |
| 52 | + double b = findKNum(A, m, B, n, len / 2 + 1); |
| 53 | + return (a + b) / 2; |
| 54 | + } |
| 55 | + |
| 56 | + return -1; |
| 57 | + } |
| 58 | + |
| 59 | + double findKNum(int *A, int m, int *B, int n, int k) |
| 60 | + { |
| 61 | + if (m > n) { |
| 62 | + return findKNum(B, n, A, m, k); |
| 63 | + } |
| 64 | + |
| 65 | + if ( m == 0) { |
| 66 | + return B[k - 1]; |
| 67 | + } |
| 68 | + if (k == 1) { |
| 69 | + return min(A[0], B[0]); |
| 70 | + } |
| 71 | + int pa = min(k / 2, m); |
| 72 | + int pb = k - pa; |
| 73 | + if (A[pa - 1] < B[pb - 1]) { |
| 74 | + return findKNum(A + pa, m - pa, B, n, k - pa); |
| 75 | + } |
| 76 | + else if (A[pa - 1] > B[pb - 1]) { |
| 77 | + return findKNum(A, m, B + pb, n - pb, k - pb); |
| 78 | + } |
| 79 | + else { |
| 80 | + return A[pa - 1]; |
| 81 | + } |
| 82 | + |
| 83 | + return -1; |
| 84 | + } |
| 85 | +}; |
| 86 | + |
| 87 | +int main() |
| 88 | +{ |
| 89 | + Solution s; |
| 90 | + |
| 91 | + int a[] = {1,2}; |
| 92 | + int b[] = {1,2}; |
| 93 | + cout << s.findMedianSortedArrays(a, 2, b, 2) <<endl; |
| 94 | + |
| 95 | + int c[] = {}; |
| 96 | + int d[] = {1,2}; |
| 97 | + cout << s.findMedianSortedArrays(c, 0, d, 2)<<endl; |
| 98 | + |
| 99 | + int e[] = {1}; |
| 100 | + int f[] = {1}; |
| 101 | + cout << s.findMedianSortedArrays(e, 1, f, 1)<<endl; |
| 102 | + return 0; |
| 103 | +} |
0 commit comments