Median of Two Sorted Arrays
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Example 1:
nums1 = [1, 3] nums2 = [2] The median is 2.0
Example 2:
nums1 = [1, 2] nums2 = [3, 4] The median is (2 + 3)/2 = 2.5
Solution:
起初没有看到要求的时间复杂度,最原始的想法就是把它们两个合在一起然后排序取中值就好。由于sort函数时间复杂度为O(NlogN),所以下面算法时间复杂度为O((m+n)log(m+n))
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
vector<int> total;
for(int i = 0; i < nums1.size(); i++)
{
total.push_back(nums1[i]);
}
for(int i = 0; i < nums2.size(); i++)
{
total.push_back(nums2[i]);
}
std::sort(total.begin(), total.end());
if(total.size() % 2 == 0) return (double)(total[total.size() / 2 - 1] + total[total.size() / 2]) * 0.5;
else return (double)total[total.size() / 2];
}
};
对算法进行改进以满足时间复杂度要求。
尝试在同一函数内寻找第K个值,可是失败了,下面函数有很多的bug,也有很多的重复之类的。放假玩崩了算了我放弃改了。
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size();
int m = nums2.size();
if (n > m) return findMedianSortedArrays(nums2, nums1);
if (n == 0)
{
if (m % 2 == 0) return (double)(nums2[(m - 1) / 2] + nums2[m / 2]) * 0.5;
else return (double)(nums2[(m - 1) / 2]);
}
if (m == 0)
{
if (n % 2 == 0) return (double)(nums1[(n - 1) / 2] + nums1[n / 2]) * 0.5;
else return (double)(nums1[(n - 1) / 2]);
}
int k = (n + m - 1) / 2; //k 为中位数所在个数
int r = k, l = 0, j = k - n + 1;
while(nums2[r] > nums1[l])
{
if(r == 0) break;
int midB = (j + r) / 2;
int midA = k - midB;
if(midB == r) break;
if (nums1[midA] < nums2[midB])
{
r = midB;
l = midA;
}
else
{
j = midB;
}
if (midA != n-1 && nums1[midA + 1] >= nums2[midB])
{
r = midB;
l = midA;
break;
}
if (midA == n - 1)
{
r = midB;
l = midA;
break;
}
}
int A, B;
if(l == n - 1 && l != 0 && nums1[l - 1] > nums2[r] && r != m - 1 && nums1[l] > nums2[r + 1])
{
A = nums1[l - 1] < nums2[r + 1] ? nums1[l - 1] : nums2[r+1];
B = nums1[l - 1] > nums2[r + 1] ? nums1[l - 1] : nums2[r+1];
}
else if(l == n - 1 && r != m - 1 && nums1[l] > nums2[r + 1])
{
A = nums2[r];
B = nums2[r + 1];
}
else if(l == n - 1 && l != 0 && nums1[l - 1] > nums2[r])
{
A = nums1[l - 1];
B = nums1[l];
}
else if(r > 0 && nums2[r - 1] > nums1[n - 1])
{
A = nums2[r - n];
B = nums2[r - n + 1];
}
else if (r > 0 && nums2[r] < nums1[0])
{
if (r < m - 1 && nums2[r + 1] < nums1[0])
{
A = nums2[r];
B = nums2[r + 1];
}
else if(r == m - 1)
{
A = nums2[r];
B = nums2[r + 1];
}
}
else
{
A = nums1[l] < nums2[r] ? nums1[l] : nums2[r];
B = nums1[l] >= nums2[r] ? nums1[l] : nums2[r];
}
if ((n + m) % 2 == 1) return A;
return (A+B) / 2.0;
}
};
用递归算法成功得完成了该题目,时间复杂度为O(log(M + N))
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int a = nums1.size();
int b = nums2.size();
int k = (a + b ) / 2;
int result1 = Kth(nums1.begin(), a, nums2.begin(), b, k + 1);
if ((a + b) % 2 == 0) {
int result2 = Kth(nums1.begin(), a, nums2.begin(), b, k);
return ( (double) result1 + result2) / 2.0;
}
return result1;
}
int Kth(vector<int>::iterator start1, int a, vector<int>::iterator start2, int b, int k) {
if (a > b) return Kth(start2 , b, start1, a, k);
if (a == 0) return *(start2 + k - 1);
if (k == 1) return *start1 < *start2 ? *start1 : *start2;
int i = a < (k / 2) ? a : (k / 2);
int j = k - i;
if (*(start1 + i - 1) > *(start2 + j - 1))
return Kth(start1, a , start2 + j, b - j, k - j);
return Kth(start1 + i, a - i, start2, j, k - i);
}
};