Question
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)).
Solution 1 -- Traverse Array
Use merge procedure of merge sort here. Keep track of count while comparing elements of two arrays. Note to consider odd / even situation.
Time complexity O(n), space cost O(1).
1 public class Solution { 2 public double findMedianSortedArrays(int[] nums1, int[] nums2) { 3 int length1 = nums1.length, length2 = nums2.length, total = length1 + length2; 4 int index1 = total / 2, index2; 5 // Consider two situations: (n + m) is odd, (n + m) is even 6 if (total % 2 == 0) 7 index2 = total / 2 - 1; 8 else 9 index2 = total / 2; 10 // Traverse once to get median 11 int p1 = 0, p2 = 0, p = -1, tmp, median1 = 0, median2 = 0; 12 while (p1 < length1 && p2 < length2) { 13 if (nums1[p1] < nums2[p2]) { 14 tmp = nums1[p1]; 15 p1++; 16 } else { 17 tmp = nums2[p2]; 18 p2++; 19 } 20 p++; 21 if (p == index1) 22 median1 = tmp; 23 if (p == index2) 24 median2 = tmp; 25 } 26 if (p < index1 || p < index2) { 27 while (p1 < length1) { 28 tmp = nums1[p1]; 29 p1++; 30 p++; 31 if (p == index1) 32 median1 = tmp; 33 if (p == index2) 34 median2 = tmp; 35 } 36 while (p2 < length2) { 37 tmp = nums2[p2]; 38 p2++; 39 p++; 40 if (p == index1) 41 median1 = tmp; 42 if (p == index2) 43 median2 = tmp; 44 } 45 } 46 return ((double)median1 + (double)median2) / 2; 47 } 48 }
Solution 2 -- Binary Search
General way to find Kth element in two sorted arrays. Time complexity O(log(n + m)).
1 public class Solution { 2 public double findMedianSortedArrays(int[] nums1, int[] nums2) { 3 int m = nums1.length, n = nums2.length; 4 if ((m + n) %2 == 1) 5 return findKthElement(nums1, nums2, (m + n) / 2, 0, m - 1, 0, n - 1); 6 else 7 return (findKthElement(nums1, nums2, (m + n) / 2, 0, m - 1, 0, n - 1) * 0.5 + 8 findKthElement(nums1, nums2, (m + n) / 2 - 1, 0, m - 1, 0, n - 1) * 0.5); 9 } 10 11 private double findKthElement(int[] A, int[] B, int k, int startA, int endA, int startB, int endB) { 12 int l1 = endA - startA + 1; 13 int l2 = endB - startB + 1; 14 if (l1 == 0) 15 return B[k + startB]; 16 if (l2 == 0) 17 return A[k + startA]; 18 if (k == 0) 19 return A[startA] > B[startB] ? B[startB] : A[startA]; 20 int midA = k * l1 / (l1 + l2); 21 // Note here 22 int midB = k - midA - 1; 23 midA = midA + startA; 24 midB = midB + startB; 25 if (A[midA] < B[midB]) { 26 k = k - (midA - startA + 1); 27 endB = midB; 28 startA = midA + 1; 29 return findKthElement(A, B, k, startA, endA, startB, endB); 30 } else if (A[midA] > B[midB]) { 31 k = k - (midB - startB + 1); 32 endA = midA; 33 startB = midB + 1; 34 return findKthElement(A, B, k, startA, endA, startB, endB); 35 } else { 36 return A[midA]; 37 } 38 } 39 }