(lintcode)原题目:http://www.lintcode.com/zh-cn/problem/median-of-two-sorted-arrays/
(leetcode)原题目:https://leetcode.com/problems/median-of-two-sorted-arrays/description/
思路分析:这个题目常规思路很简单,合并两数组再找中位数即可,但是这样最快也是O(nlgn),但题目要求是O(lg(m+n)),所以只能用二分查找类似的方式——主要思路就是取两数组当前长度,找到当前的中位数进行比较,哪个小,就砍去对应数组的左边一半,剩下的和另外一个数组继续进行相同的操作。其实原理上,应该砍去小的数组左边的一半,大的数组右边的一半;但是砍去右边的一半,剩下的部分最后一个元素不好确定,所以一般都是只砍左边的一半。其实同时砍去大的数组右边的一半也是可以的,在函数多传入两个参数,记录当前数组最后一个元素或是用指针。以下两个链接,是我个人觉得对这个算法讲解较透彻的链接:
讲解链接:http://blog.csdn.net/ojshilu/article/details/15027309
https://discuss.leetcode.com/topic/16797/very-concise-o-log-min-m-n-iterative-solution-with-detailed-explanation
代码实现:
double FindMedianSortedArrays(vector<int>& A, int a_start, vector<int>& B, int b_start,int key)
{
if (A.size() - a_start > B.size() - b_start) //统一情况,每次假定A的长度小于等于B,这样不用每次操作两种情况:A的长度小于等于B,A的长度大于B;
return FindMedianSortedArrays(B, b_start, A, a_start, key);
if (0 == A.size() - a_start) //因为B的长度总是大于等于A,所以若是A的剩余长度为0,那么刚好要找的数就是B中的第key个数
return B[key - 1];
if (1 == key)
return A[a_start] < B[b_start] ? A[a_start] : B[b_start];
int a_mid = key / 2 < (A.size() - a_start) ? a_start + key / 2 : A.size(); //要定位A的最右边那个数,所以要加上起始位置,不然坐标不对
int b_mid = key - a_mid + b_start + a_start; //定位B的最右边那个数
if (A[a_mid - 1] < B[b_mid - 1])
return FindMedianSortedArrays(A,a_mid,B,b_start,key - a_mid + a_start);
else if (A[a_mid - 1] > B[b_mid - 1])
return FindMedianSortedArrays(A, a_start, B, b_mid, key - b_mid + b_start);
else
return A[a_mid - 1];
return 0;
}
double findMedianSortedArrays(vector<int> &A, vector<int> &B)
{
int a_len = A.size();
int b_len = B.size();
if (a_len <= 0 && b_len <= 0)
return 0;
int total_len = a_len + b_len;
if (total_len % 2 != 0)
return FindMedianSortedArrays(A, 0, B, 0, total_len / 2 + 1);
else
return (FindMedianSortedArrays(A, 0, B, 0, total_len / 2) + FindMedianSortedArrays(A, 0, B, 0, total_len / 2 + 1)) / 2.0;
}