解法一
求两个序列的中位数,可以归约到求这两个序列的第 个数。
利用分治的思想,如果 ,那么 中前 个元素都不可能是答案
时间复杂度 ,空间复杂度
class Solution {
int sol(vector<int> s1, vector<int> s2, int k) { //寻找第 k 个数字
if(s1.empty()) return s2[k - 1];
if(s2.empty()) return s1[k - 1];
if(k == 1) return s1[0] < s2[0] ? s1[0] : s2[0];
int n = s1.size(), m = s2.size();
int i = min(n, k / 2) - 1, j = min(m, k / 2) - 1;
if(s1[i] < s2[j])
return sol(vector<int>(s1.begin() + i + 1, s1.end()), s2, k - i - 1);
else
return sol(s1, vector<int>(s2.begin() + j + 1, s2.end()), k - j - 1);
}
public:
int medianSearch(vector<int>& s1, vector<int>& s2) {
int n = s1.size(), m = s2.size(), k = (n + m + 1) / 2;
return sol(s1, s2, k);
}
};
解法二
假设中位数在 中,那么中位数 一定满足 ,利用二分枚举 即可
解释如下:
时间复杂度 ,空间复杂度
class Solution {
int sol(vector<int> s1, vector<int> s2, int k) {
int n = s1.size(), m = s2.size();
int l = 0, r = n - 1, ans = -1;
while(r >= l and ans == -1) {
int i = l + r >> 1, j = k - i - 1;
if(j < 0) break; // j 下溢
if(j == 0 and s1[i] <= s2[j]) ans =s1[i];
if(j > m) break; // j 上溢
if(s1[i] >= s2[j - 1]) {
if(j == m) ans = s1[i];
else {
if(s1[i] <= s2[j]) ans = s1[i];
}
}
if(s1[i] > s2[j]) {
r = i - 1;
}
else {
l = i + 1;
}
}
return ans;
}
public:
int medianSearch(vector<int>& s1, vector<int>& s2) {
int n = s1.size(), m = s2.size(), k = (n + m + 1) / 2;
int ans = sol(s1, s2, k);
if(ans == -1) ans = sol(s2, s1, k);
return ans;
}
};