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

这个题乍一看第一反应是类似链表合并的思路,两个下标分别从两个数组的开头往后数,谁的数小谁的下标就往后走,直到走到两个数组元素总数的一半为止。这种方法肯定非常快,能达到O(log(m+n)),但是边界条件太多,非常容易出错。而且这个题的等级是Hard,根据OJ尿性准则,这个题逼格肯定不会低的。想不到什么别的好办法了,于是各种博客里找方法,发现大家都很推崇其中一种方法。
这种方法把这个题给扩展了,它不仅仅找中位数,它找第k小的数,这样中位数就相当于找第k/2+1小的数(两数组的元素个数之和为奇数)或者第k/2小的数和第k/2+1小的数之和的一半(两数组的元素之和为偶数)。这个问题就此被一般化了。那么这个一般化的问题该怎么解答呢?
我们假设有数组A和B,数组A的元素个数为m,数组B的元素个数为n,寻找第k小的元素。
关键是它比较A[k/2]和B[k/2]的大小(先假设m和n都是大于k/2的),如果A[k/2] > B[k/2],那么第k小的数一定不在B的前k/2个元素中(假设第k小的元素在B的前k/2个元素中,是B的第j个元素,则j<=k/2,假设比B[j]小的A中的最大元素为A[i],则有i+j=k,则i>=k/2,则B[k/2]>=B[j]>A[i]>=A[k/2],结果B[k/2]大于A[k/2],与条件不符)。这样就把B的前k/2个元素去除,求A和B的剩下元素的第k-k/2小的元素即可。
A[k/2] < B[k/2]的时候同理。

代码如下:
 1 class Solution {
 2 public:
 3     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
 4         int sum_size(nums1.size() + nums2.size());
 5         if (sum_size % 2 == 0){
 6             return (kth_small(nums1, nums2, 0, 0, sum_size / 2) + kth_small(nums1, nums2, 0, 0, sum_size / 2 + 1)) / 2;
 7         }
 8         else{
 9             return kth_small(nums1, nums2, 0, 0, sum_size / 2 + 1);
10         }
11     }
12 private:
13     double kth_small(vector<int>& nums1, vector<int>& nums2, unsigned int cursor_left_nums1, unsigned int cursor_left_nums2, unsigned int k){
14         if (cursor_left_nums1 >= nums1.size())
15             return nums2[cursor_left_nums2 + k - 1];
16         if (cursor_left_nums2 >= nums2.size())
17             return nums1[cursor_left_nums1 + k - 1];
18         if (1 == k)
19             return min(nums1[cursor_left_nums1], nums2[cursor_left_nums2]);
20 
21         if ((cursor_left_nums1 + k / 2 - 1) >= nums1.size()){
22             return kth_small(nums1, nums2, cursor_left_nums1, cursor_left_nums2 + k / 2, k - k / 2);
23         }
24         else if ((cursor_left_nums2 + k / 2 - 1) >= nums2.size()){
25             return kth_small(nums1, nums2, cursor_left_nums1 + k / 2, cursor_left_nums2, k - k / 2);
26         }
27         else{
28             if (nums1[cursor_left_nums1 + k / 2 - 1] < nums2[cursor_left_nums2 + k / 2 - 1])
29                 return kth_small(nums1, nums2, cursor_left_nums1 + k / 2, cursor_left_nums2, k - k / 2);
30             else
31                 return kth_small(nums1, nums2, cursor_left_nums1, cursor_left_nums2 + k / 2, k - k / 2);
32         }
33     }
34 };