題意很簡單,就是給兩個排好序的數組,要求這兩個數組的中位數,題目要求複雜度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;
}
};