7.1~7.10号去南京玩了,所以没有刷题。现在回来了,题目继续搞起吧~
LintCode Median of Two Sorted Array
HARD题,没做出来。
看完网上的思路来总结一下:
这题可以转换为topK问题来解决,已知有序数组A和数组B,其合并后的中位数就是求其第k(k = (A.size+B.size)/2 )小数的问题。我们可以分别在数组A和B中考虑第k/2数,即A[k/2-1]和B[k/2-1],那么就可以分为三种情况:
1)A[k/2-1] < B[k/2-1],那么小于A[k/2-1]的数最多就有A[0],A[1],..A[k/2-2]和B[0],B[1],…,B[k/2-2],即k-2个数,也就是A[k/2-1]至多是k-1小的数,永远不可能是第k小的数。所以A[0],..,A[k/2-1]这些数都可以丢弃,那么原问题就变成了在新的两个有序数组中求第k/2小数。
2)A[k/2-1] > B[k/2-1],同样可以跟上面考虑。
3)如果两者相等,那么A[k/2-1]就是想要的第k小的数。
那么代码如下:
double findMedianSortedArrays(vector<int> A, vector<int> B) {
// write your code here
int total = A.size()+B.size();
if (total % 2 == 1) {
return findKth(A, 0, B, 0, total/2+1);
} else {
return (findKth(A, 0, B, 0, total/2)+findKth(A, 0, B, 0, total/2+1))/2;
}
}
double findKth(vector<int> A, int i, vector<int> B, int j, int k) { //i和j代表数组A和B的起始位置
//首先确保A的size小于B的size,如果不是,则交换两个数组即可。
if (A.size()-i > B.size()-j) return findKth(B, j, A, i, k);
//如果A数组为空,那么就返回B数组的第k小数
if (A.size() == i) return B[j+k-1];
//k == 1是递归终止的条件,即分治法最终截止的条件。
if (k == 1) return min(A[i], B[j]);
//pa代表的是数组A的第k/2小数,如果A.size < k/2就取最后一个数,pb同理
int pa = min(i+k/2, int(A.size())), pb = min(j+k/2, int(B.size()));
//按照上述讨论的三种情况,分别递归
if (A[pa-1] < B[pb-1])
return findKth(A, pa, B, j, k-pa+i);//舍弃A[i:pa-1]的数,则从第k小变成了第k-pa+i小
else if (A[pa-1] > B[pb-1])
return findKth(A, i, B, pb, k-pb+j);
else
return A[pa-1];
}
这个代码自己都看着晕乎了,简化一下:
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size(), n = nums2.size();
return (findKth(nums1, nums2, (m + n + 1) / 2) + findKth(nums1, nums2, (m + n + 2) / 2)) / 2.0;
}
int findKth(vector<int> nums1, vector<int> nums2, int k) {
int m = nums1.size(), n = nums2.size();
if (m > n) return findKth(nums2, nums1, k);
if (m == 0) return nums2[k - 1];
if (k == 1) return min(nums1[0], nums2[0]);
int i = min(m, k / 2), j = min(n, k / 2);
if (nums1[i - 1] > nums2[j - 1]) {
return findKth(nums1, vector<int>(nums2.begin() + j, nums2.end()), k - j);
} else {
return findKth(vector<int>(nums1.begin() + i, nums1.end()), nums2, k - i);
}
return 0;
}
};