diff --git a/CONTRIBUTERS.md b/CONTRIBUTERS.md index 03220a9..44b8f2e 100644 --- a/CONTRIBUTERS.md +++ b/CONTRIBUTERS.md @@ -64,3 +64,4 @@ * @koffy1 * @deepsourcebot * @Meaha7 +* @vedic-kalra diff --git a/LeetCode/Hard/4. Median of Two Sorted Arrays.cpp b/LeetCode/Hard/4. Median of Two Sorted Arrays.cpp index fd471b2..502bb34 100644 --- a/LeetCode/Hard/4. Median of Two Sorted Arrays.cpp +++ b/LeetCode/Hard/4. Median of Two Sorted Arrays.cpp @@ -1,78 +1,77 @@ -// Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. +/*Suppose the two arrays are A and B. +Perform the following variant of binary search first in A then B to find the median. -// The overall run time complexity should be O(log (m+n)). +Start from low = 0, high = |A|, guess i = floor (low + high)/2 +For the median m, there should be total half = floor (|A| + |B| + 1) / 2 elements not greater than it. +Since there are i + 1 elements not greater than A[i] in A, +There should be half - (i + 1) elements not greater than A[i] in B. +Denote j = half - i - 2, thus we can compare if B[j] <= A[i] <= B[j + 1] is satisfied. This indicates +That the guess is the correct median. -// Example 1: +Otherwise, we can easily tell if the guess is too small or too big, then halve the elements to adjust +the guess.*/ -// Input: nums1 = [1,3], nums2 = [2] -// Output: 2.00000 -// Explanation: merged array = [1,2,3] and median is 2. -// Example 2: +#define min(x, y) (x < y ? x : y) -// Input: nums1 = [1,2], nums2 = [3,4] -// Output: 2.50000 -// Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5. +int odd(int n) { return n & 0x1; } - +void swap(int *x, int *y) { + int tmp = *x; *x = *y; *y = tmp; +} +/* meidan of an array */ +double medianof(int A[], int n) { + return odd(n) ? (double) A[n / 2] : (double)(A[ n / 2] + A[n / 2 - 1]) / 2.0; +} -//Approach 1 - -class Solution { -public: - double findMedianSortedArrays(vector& nums1, vector& nums2) { - for(int i=0;i= n) { + if (j == -1 && A[i] <= B[0]) + return i; /* found */ + if (j >= n ) + l = i + 1; /* too small */ + else + u = i; /* too big */ + } else { + if (B[j]<= A[i] && (j == n - 1 || A[i] <= B[j+1])) + return i; /* found */ + else if (A[i] < B[j]) + l = i + 1; /* too small */ + else + u = i; /* too big */ } - sort(nums1.begin(),nums1.end()); - int n=nums1.size(); - double res; - if(n&1) - res=nums1[n/2]; - else if(!(n&1)) - res=(double)(nums1[n/2]+nums1[(n/2)-1])/2; - - return res; - } -}; - + return -1; +} -// Approach 2 - -class Solution { -public: - double findMedianSortedArrays(vector& nums1, vector& nums2) { - if(nums2.size() < nums1.size()) return findMedianSortedArrays(nums2, nums1); - int n1 = nums1.size(); - int n2 = nums2.size(); - int low = 0, high = n1; - - while(low <= high) { - int cut1 = (low+high) >> 1; - int cut2 = (n1 + n2 + 1) / 2 - cut1; - - - int left1 = cut1 == 0 ? INT_MIN : nums1[cut1-1]; - int left2 = cut2 == 0 ? INT_MIN : nums2[cut2-1]; - - int right1 = cut1 == n1 ? INT_MAX : nums1[cut1]; - int right2 = cut2 == n2 ? INT_MAX : nums2[cut2]; - - - if(left1 <= right2 && left2 <= right1) { - if( (n1 + n2) % 2 == 0 ) - return (max(left1, left2) + min(right1, right2)) / 2.0; - else - return max(left1, left2); - } - else if(left1 > right2) { - high = cut1 - 1; - } - else { - low = cut1 + 1; - } - } - return 0.0; +double findMedianSortedArrays(int A[], int m, int B[], int n) { + int i, j, k, *C; + if (!A || m == 0) + return medianof(B, n); + if (!B || n == 0) + return medianof(A, m); + if ((i = find(A, m, B, n)) == -1) { + i = find(B, n, A, m); + C = A; A = B; B = C; + swap(&m, &n); } -}; + if (odd(m + n)) + return (double)A[i]; + j = (m + n) / 2 - i - 2; + if (i == m - 1) + k = B[j+1]; + else if (j == n - 1) + k = A[i+1]; + else + k = min(A[i+1], B[j+1]); + return (double)(A[i] + k) / 2.0; +}