Leetcode the second question, Median of two Sorted Arrays

Source: Internet
Author: User
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 ....

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.