#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
/*
在两个有序的数组里面找topK的数组有这样的规律:
每次排除k/2个元素,这样可以保证对数时间,每次分别取出两个数组的第k/2个
数字,进行比较,A[k/2 - 1]和B[k/2 - 1]
1. 如果A[k/2 - 1] < B[k/2 - 1]:那么A的前k/2个都不可能是topK。
2. 如果A[k/2 - 1] > B[k/2 - 1]:那么B的前k/2个都不可能是topK。
3. 如果A[k/2 - 1] == B[k/2 - 1]:那么A的A[k/2 - 1]就是topK。
数组A的长度是a,数组B的长度是b,找中位数:
1. 如果a+b是奇数,中位数就是top[(a+b)/2 + 1]
2. 如果a+b是偶数,中位数就是(top[(a+b)/2] + top[(a+b)/2 + 1]) / 2.0
每次排除的数字的个数最多是k/2,而且要用长度较小的数组的a做边界。
终止条件:
1. 有vector是空的。
2. 当k=1。
*/
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int len1 = int(nums1.size());
int len2 = int(nums2.size());
int len = len1 + len2;
if (len % 2 != 0) {
return topk(nums1.begin(), nums2.begin(), len1, len2, len / 2 + 1);
} else {
return (topk(nums1.begin(), nums2.begin(), len1, len2, len / 2) + topk(nums1.begin(), nums2.begin(), len1, len2, len / 2 + 1)) / 2.0;
}
}
private:
double topk(vector<int>::iterator shorter, vector<int>::iterator longer, int sLen, int lLen, int k) {
if (sLen > lLen) {
return topk(longer, shorter, lLen, sLen, k);
}
if (sLen == 0) {
return *(longer + k - 1);
}
if (k == 1) {
return min(*shorter, *longer);
}
int sDel = min(sLen, k / 2);
int lDel = k - sDel;
if (*(shorter + sDel - 1) > *(longer + lDel - 1)) {
return topk(shorter, longer + lDel, sLen, lLen - lDel, k - lDel);
} else if (*(shorter + sDel - 1) < *(longer + lDel - 1)) {
return topk(shorter + sDel, longer, sLen - sDel, lLen, k - sDel);
} else {
return *(shorter + sDel - 1);
}
}
};
int main(int argc, const char * argv[]) {
vector<int> s = {1,3,5,7};
vector<int> l = {2,4,6,8};
Solution so;
cout << so.findMedianSortedArrays(s, l) << endl;
return 0;
}
leetcode-4-Median of Two Sorted Arrays
最新推荐文章于 2023-12-16 16:41:11 发布