LeetCode 4.Median of Two Sorted Arrays(双二分)
题意很简单,就是给两个排好序的数组,要求这两个数组的中位数,题目要求复杂度O(log(n+m)),虽然我知道题目数据不可能卡到这个程度的,这样的数据量C++早爆内存了,但是我很倔强,于是……
说重点,这个题我的大体思路就是对第一个数组二分,然后二分查找到第二个数组里面小于这个数字的数量,如果正好两个数组一共有(n+m-1)/2个数字比当前数小,跳出,如果少于(n+m-1)/2,那么中位数要往右找,否则往左找,但是实际操作的时候就发现有很多中复杂情况需要处理。几经修改,实在写得太矬了,直接贴代码吧。大体思路就是这样,自己写一下也许就找到更好的方法了。
#include <algorithm>
class Solution {
public:
double cul(vector<int>& nums1, vector<int>& nums2, int f) {
int n = nums1.size(), m = nums2.size();
if(!n) {
return (m & 1) ? nums2[m / 2] : (nums2[m / 2] + nums2[m / 2 - 1]) / 2.0;
}
if(!m) {
return (n & 1) ? nums1[n / 2] : (nums1[n / 2] + nums1[n / 2 - 1]) / 2.0;
}
int h = (n + m - 1) >> 1;
int b1 = 0, b2 = 0, e1 = nums1.size() - 1, e2 = nums2.size() - 1, h1, h2, x;
while(b1 <= e1) {
h1 = (b1 + e1) >> 1;
int tb = b2, te = e2;
while(tb < te) {
h2 = (tb + te) >> 1;
if(nums2[h2] < nums1[h1] + f) {
tb = h2 + 1;
}
//else if(tb == te + 1) break;
else
te = h2;
}
h2 = tb;
x = (nums2[h2] < nums1[h1]);
if(h1 + h2 + x < h) {
b1 = h1 + 1;
b2 = h2;
}
else if(h1 + h2 + x > h) {
e1 = h1 - 1;
e2 = h2;
}
else break;
}
//printf("%d %d %d\n", h1, h2, x);
if(b1 > e1)
return -1e20 - 1e10;
if((n + m) & 1) {
//if(nums1[h1] > nums2[h2]) return nums1[h1];
return nums1[h1];
}
else {
if(x) return (nums1[h1] + nums1[h1 + 1]) / 2.0;
int t = nums2[h2];
if(h1 < n - 1 && nums1[h1 + 1] < t) t = nums1[h1 + 1];
return (nums1[h1] + t) / 2.0;
}
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
double ans = max(cul(nums1, nums2, 0), cul(nums1, nums2, 1));
if(ans < -1e20) ans = max(cul(nums2, nums1, 1), cul(nums2, nums1, 0));
return ans;
}
};