给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
将nums1和nums2合并成一个有序数组,然后直接取中位数。
class Solution {
public:
double findMedianSortedArrays(vector& nums1, vector& nums2) {
int l1 = nums1.size(), l2 = nums2.size();
int p1 = 0, p2 = 0;
vector nums;
for(int i = 0; i < l1 + l2; i++) {
int n1 = p1 >= l1? 99999999 : nums1[p1];
int n2 = p2 >= l2? 99999999 : nums2[p2];
if(n1 > n2) {
nums.push_back(n2);
p2++;
}
else {
nums.push_back(n1);
p1++;
}
}
if((l1 + l2) % 2 == 0) {
double res = (nums[(l1 + l2)/2] + nums[(l1 + l2) / 2 - 1]) / 2.0;
return res;
}
else
return nums[(l1 + l2)/2];
}
};
主要是利用中位数的性质,把2个数组分别再分成2部分,逐渐调整分割位置,直到找到所有比中位数小的数。具体可以参考下文:
原文链接
class Solution {
public:
double findMedianSortedArrays(vector& nums1, vector& nums2) {
int m = nums1.size(), n = nums2.size();
if(m > n) {
vector temp = nums1; nums1 = nums2; nums2 = temp;
int tmp = m; m = n; n = tmp;
}
//print(nums1);
//print(nums2);
int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;
while(iMin <= iMax) {
int i = (iMin + iMax) / 2;
int j = halfLen - i;
if(i < iMax && nums2[j - 1] > nums1[i]) {
cout<<"judge1: "< iMin && nums1[i - 1] > nums2[j]) {
//cout<<"judge2: "<
和方法二类似,但是解决了数组奇偶性的问题。具体原文链接如下:
原文链接
class Solution {
public:
double MidofArray(vector &nums) {
int mid = nums.size() / 2;
int flag = ! (nums.size() % 2);
return (nums[mid] + nums[mid - flag]) / 2.0;
}
double findMedianSortedArrays(vector& nums1, vector& nums2) {
if(nums1.size() == 0)
return MidofArray(nums2);
if(nums2.size() == 0)
return MidofArray(nums1);
int n = nums1.size(), m =nums2.size();
if(n > m)
return findMedianSortedArrays(nums2, nums1);
int L1, L2, R1, R2, c1, c2, lo = 0, hi = 2 * n;
while(lo <= hi) {
c1 = (lo + hi) / 2;
c2 = m + n - c1;
L1 = (c1 == 0) ? INT_MIN : nums1[(c1 - 1) /2];
R1 = (c1 == 2 * n) ? INT_MAX : nums1[c1 /2];
L2 = (c2 == 0) ? INT_MIN : nums2[(c2 - 1) /2];
R2 = (c2 == 2 * m) ? INT_MAX : nums2[c2 /2];
if(L1 > R2)
hi = c1 - 1;
else if(L2 > R1)
lo = c1 + 1;
else
break;
}
return (max(L1, L2) + min(R1, R2)) / 2.0;
}
};
这道题一开始只会暴力法,看了递归和分治好久才看懂,好好学习天天向上!