问题 :
对于两个长度均为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; }