问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回下中位数)。
解题思路是利用了二分的思想,假设两个数组存在中位数mid,然而一定有(len(num1)+len(num2))/2个数小于中位数mid,我们就利用这一点来进行递推.
假设我们取数组1的中位数mid1,数组1中有len(num1)/2个数小于mid1,如果mid1为整个序列的中位数,那么num2中一定有(len(num1)+len(num2))/2-len(num1)/2个数小于mid1.这时我们就可以根据num2这个位置的下一位与mid1比较,这样就可以缩小判定范围.
如果num1为1,2,3,4,5num2为6,7,8,9,10,11.
那么第一步比较就是3和9比较,为什么呢,因为一共有11个数那么如果3为中位数一定有5个数小于它,在num1中已经有两个数小于它,所以判断num2中是否有3个数小于它,根据两个数的大小来缩小判断的范围,上面的例子中3小于9则可以排除1,2,3和9,10,11.为什么呢,还是因为最开始的那个公式,这几个数已经不符合中位数的硬性条件也就是一定有(len(num1)+len(num2))/2个数小于中位数.这样我们就变成了判断4,5和9,10,11的中位数,依次循环就OK了.
#include "stdio.h"
#include "iostream"
#include "vector"
using namespace std;
double fun(vector& vec1, vector& vec2)
{
int N1 = vec1.size(), N2 = vec2.size();
int medean = (N1 + N2 + 1) / 2, i = 0, j = 0;
for(int k = 1; k < medean; k++)
{
if(i < N1 && j < N2)
{
if(vec1[i] < vec2[j])i++;
else j++;
}
else if(i >= N1)//数组vec1到达末尾
j++;
else if(j >= N2)//数组vec2到达末尾
i++;
}
if(i < N1 && j < N2)
return vec1[i] < vec2[j] ? vec1[i] : vec2[j];
else if(i >= N1)
return vec2[j];
else if(j >= N2)
return vec1[i];
}
int main()
{
vector num1,num2;
double Num;
num1.push_back(1);
num2.push_back(2);
num2.push_back(3);
Num = fun(num1,num2);
printf("%.1lf\n",Num);
return 0;
}