LintCode: Median of two Sorted Arrays

时间:2021-12-13 12:52:04

求第k个值

1.归并排序

归并到第k个值为止

时间复杂度:O(k)

 class Solution {
public:
// merge-sort to find K-th value
double helper(vector<int> A, vector<int> B, int lenA, int lenB, int k) {
int i = , j = ;
while ((i < lenA) && (j < lenB)) {
k--;
if (A[i] < B[j]) {
if ( == k) {
return A[i];
}
++i;
} else if ( == k) {
return B[j];
} else {
++j;
}
}
return (i >= lenA)?B[j + k - ]:A[i + k - ];
}
/**
* @param A: An integer array.
* @param B: An integer array.
* @return: a double whose format is *.5 or *.0
*/
double findMedianSortedArrays(vector<int> A, vector<int> B) {
// write your code here
int m = A.size();
int n = B.size();
return ((m + n) & )?
(helper(A, B, m, n, (m + n + )>>)):
(((helper(A, B, m, n, ((m + n)>>) + ))+(helper(A, B, m, n, (m + n)>>))) * .);
}
};

2. 分治法

利用归并的思想,从a和b中一共取k个数

假设len(a)<len(b)

从a中取pa = min(k/2, len(a))个元素;

从b中取pb = k-pa个元素;

如果a[pa - 1]<b[pb - 1],则归并排序时先归并a[pa - 1],说明a数组的数取“少”了,不够用

  a到终点后,只用b的数凑足了k个,这说明总的第k大的值不会出现在a[0...pa-1]里边,所以我们扔掉前pa个数

  对于b数组,说明总的第k大的数不会出现在b[pb...lenB]里边,pb后边的数就没用了

如果a[pa - 1]>=b[pb - 1],是对称情况

  归并排序时,会先归并b[pb - 1],说明b数组的数取“少”了,不够用

  b到终点后,只用a的数凑足了k个,这说明总的第k大的值不会出现在b[0...pb-1]里边,所以我们扔掉前pb个数

  对于a数组,说明第k大的数不会出现在a[pa...lenA]里边,pa的后边就没用了

总结:扔掉较小数组的前一部分,扔掉较大数组的后一部分

复杂度分析:O(logK), K每次几乎减少一半

 class Solution {
public:
// merge-sort to find K-th value
double helper(int *A, int *B, int lenA, int lenB, int k) {
if (lenA > lenB) {
return helper(B, A, lenB, lenA, k);
}
// lenA <= lenB
if (lenA == ) {
return B[k - ];
}
if ( == k) {
return min(A[], B[]);
}
int pa = min(lenA, k >> ), pb = k - pa;
return (A[pa - ] < B[pb - ])?
helper(A + pa, B, lenA - pa, lenB, k - pa):
helper(A, B + pb, lenA, lenB - pb, k - pb);
}
/**
* @param A: An integer array.
* @param B: An integer array.
* @return: a double whose format is *.5 or *.0
*/
double findMedianSortedArrays(vector<int> A, vector<int> B) {
// write your code here
int m = A.size();
int n = B.size();
return ((m + n) & )?
(helper(A.data(), B.data(), m, n, (m + n + )>>)):
(((helper(A.data(), B.data(), m, n, ((m + n)>>) + ))+(helper(A.data(), B.data(), m, n, (m + n)>>))) * .);
}
};