题目描述:(题目链接)
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)).
解题思路:
该问题可以被转化为在两个数组中找第K小的问题,
假设两个数组A和B,A.size() > k / 2,B.size() > k / 2:
1. if A[k / 2 - 1] < B[k / 2 - 1], 说明A[0] ~ A[k / 2 - 1] 出现在A和B合并数组的Top k中;
2. if A[k / 2 - 1] > B[k / 2 - 1], 与情况1类似
3. if A[k / 2 - 1] = B[k / 2 - 1], 返回A[k / 2 - 1] 或者 B[k / 2 - 1];
当然还需要考虑一些边界情况:
1. 如果A或者B有一个为空, 返回B[k - 1] 或者 A[k - 1]
2. 如果k == 1, 返回min(A[0], B[0])
C语言描述:
int min(int a, int b) {
if (a > b) {
return b;
}
return a;
}
int findKth(int *nums1, int m, int *nums2, int n, int k) {
if (m > n) { return findKth(nums2, n, nums1, m, k); }
if (m == 0) { return nums2[k - 1]; }
if (k == 1) { return min(nums1[0], nums2[0]);}
int a = min(k / 2, m);
int b = k - a;
if (nums1[a - 1] < nums2[b - 1]) {
return findKth(nums1 + a, m - a, nums2, n, k - a);
} else if (nums1[a - 1] > nums2[b - 1]) {
return findKth(nums1, m, nums2 + b, n - b, k - b);
} else {
return nums1[a - 1];
}
}
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
int total = (nums1Size + nums2Size);
if (total & 1) {
return findKth(nums1, nums1Size, nums2, nums2Size, total / 2 + 1);
} else {
return (findKth(nums1, nums1Size, nums2, nums2Size, total / 2) + findKth(nums1, nums1Size, nums2, nums2Size, total / 2 + 1)) / 2.0;
}
}
2015-10-03更新,重新用C++写了一遍,vector用的不熟,LeetCode编译器好像不支持C++ 14!
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int nums1Size = nums1.size();
int nums2Size = nums2.size();
int total = (nums1Size + nums2Size);
if (total & 1) {
return findKth(nums1.begin(), nums1Size, nums2.begin(), nums2Size, total / 2 + 1);
} else {
return (findKth(nums1.begin(), nums1Size, nums2.begin(), nums2Size, total / 2) + findKth(nums1.begin(), nums1Size, nums2.begin(), nums2Size, total / 2 + 1)) / 2.0;
}
}
int findKth(vector<int>::iterator nums1, int m, vector<int>::iterator nums2, int n, int k) {
if (m > n) { return findKth(nums2, n, nums1, m, k); }
if (m == 0) { return *(nums2 + k - 1); }
if (k == 1) { return min(*nums1, *nums2);}
int a = min(k / 2, m);
int b = k - a;
if (*(nums1 + a - 1) < *(nums2 + b - 1)) {
return findKth(nums1 + a, m - a, nums2, n, k - a);
} else if (*(nums1 + a - 1) > *(nums2 + b - 1)) {
return findKth(nums1, m, nums2 + b, n - b, k - b);
} else {
return *(nums1 + a - 1);
}
}
};