Title Reproduction
There are two sorted arrays A and B of size m and N respectively. Find the median of the two sorted arrays. The overall run time complexity should is O (log (m+n)).
The solution to the question meaning is to give two ordered arrays of size m,n (M,n may be 0), to find out the median of these two arrays. And the time complexity of the program must not exceed O (log (m+n)). The first feeling of this problem is not difficult, but the requirement of complexity. The most straightforward way to think about it is to combine two numbers into an ordered array and find the median directly. How do I combine two ordered arrays? (This topic is worth studying, check the data later or something.) First apply for a m+n array space, two copies of the array into the space, and then, using the sort function to order, and then directly look for output. The code is as follows:
Class Solution {public
:
double findmediansortedarrays (int a[], int m, int b[], int n) {
//Start typing your C + + solution below
//do not write int main () function
int *a=new int[m+n];
memcpy (a,a,sizeof (int) *m);
memcpy (a+m,b,sizeof (int) *n);
Sort (a,a+n+m);
Double median= (n+m)%2 a[(n+m) >>1]:(a[(n+m-1) >>1]+a[(n+m) >>1])/2.0);
Delete A;
return median;
}
;
But what I didn't think of was that I had passed ......... Feel that you are cheating, and the time complexity has not reached the requirements O (m+n) ............ This has been given to ........... Orz.
The Python code for this method is also well written, but,,, seemingly leetcode does not support Python's built-in methods, because when I use the sorted function, the display compiles but ...
Then there is the second solution. We can see that now we do not need to "sort" such complex operations, because we only need the K-large element. We can use a counter that records the elements that are currently found in the first M. We also use two pointer pa and PB, pointing to the first element of array A and B, respectively. Using a principle similar to the merge sort, if the current element of array A is small, then pa++ and m++. If the current element of array B is small, then pb++ and m++. Eventually when M equals K, we get our answer--o (k) Time, O (1) space.
The test code is as follows:
#include <iostream> #include <vector> #include <algorithm> using namespace std;
Class Solution {private:double findkth (int a[], int m, int b[], int n, int k) {int i = 0;
int j = 0;
int index = 1;
int kth;
if (M = = 0) return b[k-1];
if (n = = 0) return a[k-1]; if (k ==1) return a[0]>b[0]?
B[0]: a[0];
if (k = = 2) return (A[0] + b[0])/2.0;
while (index <= k && i < m && J < N) {if (A[i] >= b[j]) {index + +;
KTH = B[j];
j + +;
else {index + +;
KTH = A[i];
i + +;
} if (Index < k && J = = N) {kth = A[i+k-index];
} if (Index < k && i = = m) kth = B[j+k-index];
return kth;
public:double findmediansortedarrays (int a[], int m, int b[], int n) {int total = m + N;
Totla is even OR odd? if (Total & 0x1)//Even return findkth (A, M, B, N, Total/ 2 + 1);
else//Odd return (Findkth (A, m, B, N, TOTAL/2) + findkth (A, m, B, N, TOTAL/2 + 1))/2;
}
};
int main () {Solution S1;
int a[] = {6,7,8,9};
int b[] = {5,6};
cout << s1.findmediansortedarrays (A, 4, B, 2) << Endl;
return 0;
}
However,,,, in the leetcode inside just can't get and test the same result .... Then there is the sharp way: You can consider starting with K. If we can get rid of an element that must precede the K-large element every time, then we need to do it k times. But if every time we cut out half of it. So with this kind of binary thinking, we can consider this: (from someone else)
Assume this number of elements in a and are both larger than K/2, and if we compare the k/2-th element in a (i.e. a[k/2-1]) and the k-th smallest element in B (i.e. B[K/2-1]), there are-three:
(becasue k can be odd or even number, so we assume k are even number here for Simplicy.) The following is also true if K is a odd number.)
A[K/2-1] = b[k/2-1]
A[K/2-1] > B[k/2-1]
A[K/2-1] < b[k/2-1]
If a[k/2-1] < b[k/2-1], that's means all elements from a[0] to a[k/2-1] (i.e. the K/2 smallest elements in A) are in T He range of K smallest elements in the union of A and B. Or, in the other word, A[K/2-1] can never is larger than the k-th smalleset element in the Union of A and B.
Why?
We can use a proof by contradiction. Since A[K/2-1] is larger than the k-th smallest element in the union of A and B, then we assume it is the (k+1)-th Small EST one. Since It is smaller than B[K/2-1], then B[K/2-1] should as at least k+2 (-th) smallest one. So there are at most (k/2-1) elements smaller than-a[k/2-1] in A, and at most (K/2-1) elements smaller than] in B.so The total number are k/2+k/2-2, which, no matter when k are odd or even, is surly smaller the than K (since a[k/2-1) is the (k+1)-th smallest element). So a[k/2-1] can never larger than the k-th smallest element in the union of A and B if a[k/2-1]<b[k/2-1];
Since There is such a important conclusion, we can safely drop the A, K/2 which, are definitaly t Han k-th element in the Union of A and B. This is also true for the a[k/2-1] > b[k/2-1] condition, which we should drop the elements in B.
When a[k/2-1] = b[k/2-1], then we have found the k-th element, which is the smallest element, we can call it m. equal are each (k/2-1) numbers smaller than M with A and B, so M must is the k-th number. So we can call a function recursively, when a[k/2-1] < b[k/2-1], we drop the elements in a, else we drop the elements I N B.
We should also consider the edge case, which is, when should we stop?
1. When A or B is empty, we return b[k-1] (or a[k-1]), respectively;
2. When k is 1 (where A and B are both not empty), we return the smaller one of a[0] and b[0]
3. When a[k/2-1] = b[k/2-1], we should return one of them
In the code, we check if m are larger than N to Garentee that's the We always know the smaller array for coding simplicy.
Double findkth (int a[], int m, int b[], int n, int k)
{
//always assume, M is equal or smaller than n
if ( M > N) return
findkth (b, N, A, M, k);
if (M = = 0) return
b[k-1];
if (k = = 1) return
min (a[0], b[0]);
Divide k into two parts
int pa = min (k/2, m), PB = K-pa;
if (A[pa-1] < b[pb-1]) return
findkth (A + PA, m-pa, B, N, K-PA);
else if (A[pa-1] > B[pb-1]) return
findkth (A, m, B + Pb, N-PB, K-PB);
else return
A[pa-1];
}
Class Solution
{public
:
double findmediansortedarrays (int a[], int m, int b[], int n)
{
int Total = m + N;
if (Total & 0x1) return
findkth (A, M, B, N, TOTAL/2 + 1);
else return
(Findkth (A, m, B, N, TOTAL/2)
+ findkth (A, m, B, N, TOTAL/2 + 1))/2;
}
;
Another method: First turn to the question of the number of k in A and B arrays, and then use K/2 in A and B respectively. For example k = 6, see the 3rd number of A and b respectively, known A1 < A2 < A3 < A4 < A5 ... and B1 < B2 < B3 < B4 < B5 ... if A3 <=, then the 6th small number will certainly not be B3, A1, A2, because up to two numbers is less than A3, three is less than A1, four is less than A2. B3 is at least 5 digits, so the 6th small number may be B1 (A1 < A2 < A3 < A4 < A5 < B1), possibly B2 (A1 < A2 < A3 < B1 < A4 < B2) , it could be B3 (A1 < A2 < A3 < B1 < B2 < B3). That can be ruled out A1, A2, A3, turn to seek A4, A5, ... B1, B2, B3, ... The problem with the 3rd small number of these numbers is that K is halved. Each time you assume that a has fewer elements, the result of pa = min (k/2, LenA) can cause k = = 1 or a null, both of which are terminating conditions.
Class Solution:
# @return A float
def getmedian (self, A, B, K):
# return KTH smallest number of arrays A and B , assume Len (a) <= Len (b)
LenA = Len (a); LenB = Len (b)
if LenA > Lenb:return Self.getmedian (b, A, K)
if LenA = = 0:return B[k-1]
if k = = 1:return min (a[0], b[0])
pa = min (k/2, lenA); PB = K-pa return
self.getme Dian (A[PA:], B, K-PA) if A[pa-1] <= b[pb-1] Else Self.getmedian (A, B[PB:], K-PB)
def findmediansortedarrays (Self, A, b):
LenA = Len (a); LenB = Len (b)
if (LenA + lenB)% 2 = 1: Return
Self.getmedian (A, B, LenA + L EnB)/2 + 1
else: return
0.5 * (Self.getmedian (A, B, (LenA + LenB)/2) + Self.getmedian (A, B, (LenA + LenB) /2 + 1))
。。。。。。。。。。。。。。 This problem is not very simple ....