题目
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
思路
找出中位数其实可以泛化为求两个数组中第k大的数,此时求中位数只是其中的一个特例而已。首先看看两种平凡情况:
1)k == 1:此时只需要返回nums1和nums2的首元素的最小值即可;
2)如果nums1或者nums2为空,则直接返回另一数组中的第k个元素即可。
如果不属于平凡情况,则递归处理:分别计算nums1和nums2的第k/2个数,并比较两者的大小。如果nums1的第k/2个数小于nums2的第k/2个数,那么结果不可能出现在nums1中的前k/2个数中;此时可以减掉nums1中的前k/2个数,并进入下一次递归;如果nums1的第k/2个数大于nums2中的第k/2个数,那么结果不可能出现在nums2中的前k/2个数中,此时可以减掉nums2中的前k/2个数,并进入下一次递归。
注意在该例中k是以1为起始索引的,所以要注意转换。
代码
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int total_length = nums1.size() + nums2.size();
if(total_length % 2 != 0) // odd case
return findKth(nums1, nums2, 0, 0, total_length / 2 + 1);
else // even case
return (findKth(nums1, nums2, 0, 0, total_length / 2) +
findKth(nums1, nums2, 0, 0, total_length / 2 + 1)) / 2.0;
}
private:
double findKth(vector<int>& nums1, vector<int>& nums2, int s1, int s2, int k)
{
if(s1 >= nums1.size())
return nums2[s2 + k - 1];
if(s2 >= nums2.size())
return nums1[s1 + k - 1];
if(k == 1)
return min(nums1[s1], nums2[s2]);
int nums1_key = s1 + k / 2 - 1 >= nums1.size() ? INT_MAX : nums1[s1 + k / 2 - 1];
int nums2_key = s2 + k / 2 - 1 >= nums2.size() ? INT_MAX : nums2[s2 + k / 2 - 1];
if(nums1_key < nums2_key) // drop the first half of nums1
return findKth(nums1, nums2, s1 + k / 2, s2, k - k / 2);
else // drop the first half of nums2
return findKth(nums1, nums2, s1, s2 + k / 2, k - k / 2);
}
};