Median of Two Sorted Arrays
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 be O(log (m+n)).
思路
题目最后要求给出的算法复杂度是O(log(m+n)),很明显这道题要用二分的想法去做。所以就开始考虑通过比较A[mid]和B[mid]之间的关系来到达二分的效果。算了半天发现不太对劲,搞不出来啊。还要考虑m和n之间的大小,一头雾水。于是,我又一次厚着脸皮看了下别人的题解,嘻嘻。虽然我现在很渣,但是我相信,以后我会很拽。
其实之前的思路大致方向是对的,但是对二分的理解也不是很彻底,思路被局限死了。应该通过二分,筛选掉一半的一半,之后进行递归。这样算法的复杂度就是O(log((m+n)/2))。
这里可以考虑这道题的普遍结论,求出两个数列合并后的第k个元素,想法是类似的。
首先将k个元素分成数量为ta和tb两个部分,比较A[ta-1]和B[tb-1]的大小,筛选掉其中某一部分的一半。比如,
如果A[ta-1]>B[tb-1],那么可以断言在前k-1小的元素集合中一定包含B[0...tb-1]这tb个元素。每次的操作,至多减少k/2个元素,所以整个算法的复杂度是O(logk)。
具体的可以看代码。
代码
!!!什么,竟然WA。这种代码一定不是我写的。
if ((m+n)%2)
好吧,我承认我是逗比。这个错误看了10+分钟。下面是AC的代码
class Solution {
public:
double findKthElement(int A[], int m, int B[], int n, int k) {
if (m < n) {
return findKthElement(B, n, A, m, k);
}
if (n == 0) return A[k-1];
if (k == 1) return min(A[0], B[0]);
int tb = min(k/2, n);
int ta = k-tb;
if (A[ta-1] > B[tb-1]) {
return findKthElement(A, m, B+tb, n-tb, k-tb);
}
if (A[ta-1] < B[tb-1]) {
return findKthElement(A+ta, m-ta, B, n, k-ta);
}
if (A[ta-1] == B[tb-1]) {
return A[ta-1];
}
}
double findMedianSortedArrays(int A[], int m, int B[], int n) {
if ((m+n)%2 == 0) {
return (findKthElement(A, m, B, n, (m+n)/2)+findKthElement(A, m, B, n, (m+n)/2+1))/2;
}
else {
return findKthElement(A, m, B, n, (m+n+1)/2);
}
}
};