问题 :
对于两个长度均为n的已排序的序列,确定这两个序列的2n个元素的中位数。
解决此问题的算法思想:
设两个长度为n的数列分别为x[ 0 : n -1]和y[ 0 : n -1],分别找出这两个数列的中位数x[i]和
y[ j ],二者进行比较,根据比较结果可以在每个数列中减少一半的搜索范围,然后再分别取
两个子数列的中位数再比较,再减少搜索范围,继续下去直到找到最后结果。采用分治法来做,时间复杂度:O(lgn).
网址:中位数问题 对这个问题进行了较为深入的阐述。下面给出了Python的代码实现:
def fidMid(cx1,cx2):
size = len(cx1)
mid = (size -1) //2
midSize = mid
if(size %2 == 0):
midSize = mid+1
if (size ==1 ):
if(cx1[0] >=cx2[0]):
return cx2[0]
else:
return cx1[0]
if(cx1[mid] <=cx2[mid]):
for i in range(0, midSize):
cx1.pop(0)
cx2.pop()
else:
for i in range(0, midSize):
cx1.pop()
cx2.pop(0)
return fidMid(cx1, cx2)
if '__name__ = __main__' :
x=[10, 15, 16, 19]
y=[11, 17, 18, 20]
print(fidMid(x, y))
复杂性分析:采用了二分查找的办法,树的节点个数为2n,因此算法的时间复杂度为= .
下面是网上别人的C++代码:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
#include<stdlib.h>
int findMiddle(vector<int> a, vector<int> b)
{
int size = a.size();
int mid_size = size/2;
if(size == 1)
{
if(a[0] > b[0])
return b[0];
else
return a[0];
}
if(a[mid_size] < b[mid_size])
{
copy (a.begin()+mid_size, a.end(),
a.begin());
for(int i = 0; i < mid_size; i++)
{
a.pop_back();
}
if((size%2) == 0)
{
for(int j = mid_size; j < size; j++)
{
b.pop_back();
}
}
else
{
for(int j = mid_size; j < size - 1; j++)
{
b.pop_back();
}
}
return findMiddle(a,b);
}
else if(a[mid_size] > b[mid_size])
{
copy (b.begin()+mid_size, b.end(),
b.begin());
for(int i = 0; i < mid_size; i++)
{
b.pop_back();
}
if((size%2) == 0)
{
for(int j = mid_size; j < size; j++)
{
a.pop_back();
}
}
else
{
for(int j = mid_size; j < size - 1; j++)
{
a.pop_back();
}
}
return findMiddle(a,b);
}
else
return a[mid_size];
}
int main()
{
vector<int> a;
vector<int> b;
int number;
int mid_number;
int temp = 0;
int i = 0;
int j = 0;
ifstream infile;
ofstream outfile;
infile.open("middleNumber.txt");
outfile.open("out.txt");
if(!infile)
{
cerr << "Can not open middleNumber file!" << endl;
return 0;
}
if(!outfile)
{
cerr << "Can not open OUT file!" << endl;
return 0;
}
infile >> number;
for(i = 0; i < number; i++)
{
infile >> temp;
a.push_back(temp);
}
for(i = 0; i< number; i ++)
{
infile >> temp;
b.push_back(temp);
}
// cout << a[0] << " " << a[1] << " " << a[2] << endl;
// cout << b[0] << " " << b[1] << " " << b[2] << endl;
mid_number = findMiddle(a,b);
outfile << mid_number;
cout << mid_number << endl;
return 0;
}