Description:
LetX[1 ..N] AndY[1 ..N] Be two arrays, each containingNNumbers already in sorted order. GiveO(LGN)-Time algorithm to find the median of all 2NElements in ArraysXAndY.
The topic is an exercise in introduction to algorithms, but it has appeared in interview questions many times.
Analysis given in the introduction to algorithms: (for two ordered arrays with equal lengths)
Code implementation:
Template <typename T>
T find_median (T seq1 [], t seq2 [], int N, int low, int high)
{
If (low> high)
Return (t)-999999;
Int K = (low + high)/2;
If (k = n-1 & seq1 [n-1] <= seq2 [0])
Return seq1 [n-1];
Else if (k <n-1 & seq1 [k]> = seq2 [n-k-1] & seq1 [k] <= seq2 [n-k])
Return seq1 [k];
Else if (seq1 [k]> seq2 [n-k])
Return find_median (seq1, seq2, N, low, k-1 );
Else
Return find_median (seq1, seq2, n, k + 1, high );
}
Template <typename T>
T two_array_median (T seq1 [], t seq2 [], int N)
{
T Median = find_median (seq1, seq2, N, 0, n-1 );
If (Median = (t)-999999)
Return find_median (seq2, seq1, N, 0, n-1 );
Else
Return median;
}
Problem expansion 1:
Returns the I-th element after the two ordered arrays (not necessarily the same length) are merged (not necessarily the median ).
Train of Thought Analysis:
Assume that the two ordered arrays are a [1... n] and B [1... n], because it is to find the I-th element, the element can only be in a [1... i] and B [1... i], now compare a [I/2] and B [I/2]
(1) A [I/2] = B [I/2], then a [I/2] (or B [I/2]) is the element to be searched.
(2) A [I/2]> B [I/2], then the I-th element is in a [1... i/2] and B [I/2... recursively look for the I/2 elements in the above two Arrays
(3) A [I/2] <B [I/2], then the I-th element is in a [I/2... i] and B [1... in I/2], Recursively search for the I/2 elements in the above two Arrays
Obviously, the time of the above algorithm is O (Logi ).
However, there is a defect that the I value is less than the length of the two arrays before the algorithm can get the correct result.
Code implementation:
# Include <iostream>
# Include <string>
Using namespace STD;
Template <typename T>
T median2 (T * x, t * y, int size)
{
Int M = (size-1)/2;
If (X [m] = Y [m])
Return X [m];
Else if (X [m]> Y [m])
Return size = 1? Y [m]: median2 (X, Y + size-m-1, m + 1 );
Else
Return size = 1? X [m]: median2 (x + size-m-1, Y, m + 1 );
}
Int main (INT argc, char * argv [])
{
Int T1 [] = {1, 2, 3, 4, 5, 6, 9 };
Int T2 [] = {2, 2, 3, 4, 5, 7, 8 };
Cout <"median 3:" <median2 (T1, T2, 7 );
System ("pause ");
Return 0;
}
Problem 2:
Returns the median of an ordered array of two lengths.
Train of Thought Analysis:
It is easy to find the median of each array in O (1) time.
Assume the median of array a is m and the median of array B is N.
Then,
1 'if M = N, then clearly the median after merging is also m, the algorithm holds.
2 'if m <n, then reserve the half of sequence a in which all numbers are greater
M, also reserve the half of sequence B in which all numbers are smaller than N.
Run the algorithm on the two new arrays.
3 'if m> N, then reserve the half of sequence a in which all numbers are smaller
M, also reserve the half of sequence B in which all numbers are larger than N.
Run the algorithm on the two new arrays.
Time Complexity: O (logn)
Code implementation:
# Include <iostream>
# Include <string>
Using namespace STD;
Template <typename T>
T find_median_in_two_sorted_arr (T seq1 [], t seq2 [], int len1, int len2)
{
Int MA = 0, NA = len1-1;
Int MB = 0, NB = len2-1;
While (1)
{
Int Ka = (Na + MA + 1)/2;
Int kb = (Nb + MB + 1)/2;
If (Na <Ma)
{
Return seq2 [KB];
}
If (Nb <MB)
{
Return seq1 [Ka];
}
If (seq1 [Ka] = seq2 [KB]) // find the value
{
Return seq1 [Ka];
}
If (MA = Na) & (Nb-MB + 1) % 2 = 0) // there is only one element at a []
{
If (seq1 [Na] <seq2 [KB]) & (seq1 [Na]> = seq2 [kb-1])
{
Return seq1 [Na];
}
}
If (MA = Na) & (Nb-MB + 1) % 2 ))
{
If (seq1 [Na]> seq2 [KB]) & (seq1 [Na] <= seq2 [Kb + 1])
{
Return seq1 [Na];
}
}
If (MB = Nb) & (Na-MA + 1) % 2 = 0) // there is only one element at B []
{
If (seq2 [Nb] <seq1 [Ka]) & (seq2 [Nb]> = seq1 [ka-1])
{
Return seq2 [Nb];
}
}
If (MB = Nb) & (Na-MA + 1) % 2 ))
{
If (seq2 [Nb]> seq1 [Ka]) & (seq2 [Nb] <= seq1 [Ka + 1])
{
Return seq2 [Nb];
}
}
Int offset = ka-Ma> KB-MB? KB-MB: Ka-Ma;
If (offset = 0)
Offset ++;
If (seq1 [Ka] <seq2 [KB])
{
MA + = offset;
Nb-= offset;
}
If (seq1 [Ka]> seq2 [KB])
{
Na-= offset;
MB + = offset;
}
}
}
Int main (INT argc, char * argv [])
{
Int A [] = {1, 3, 5, 7, 8, 9, 10 };
Int B [] = {2, 4, 6, 10, 11, 12, 13, 14, 17, 19, 20 };
Int sizea = sizeof (a)/sizeof (INT );
Int sizeb = sizeof (B)/sizeof (INT );
Cout <"median:" <find_median_in_two_sorted_arr (a, B, sizea, sizeb );
System ("pause ");
Return 0;
}