标签:
1 class Solution { 2 public: 3 /** 4 * @param nums: A list of integers. 5 * @return: An integer denotes the middle number of the array. 6 */ 7 void swap(vector<int> &v, int i, int j) 8 { 9 int tmp = v[i]; 10 v[i] = v[j]; 11 v[j] = tmp; 12 } 13 int getMedian(vector<int> &v, int left, int right) 14 { 15 if(left<right) 16 { 17 int i = left-1, j = left; 18 for(; j<right; ++j) 19 { 20 if(v[j]<v[right]) 21 { 22 ++i; 23 swap(v, i, j); 24 } 25 } 26 swap(v, i+1, right); 27 int sz = v.size(); 28 if((sz-1)/2==i+1) return v[i+1]; 29 else if((sz-1)/2<=i) return getMedian(v, left, i); 30 else return getMedian(v, i+2, right); 31 } 32 else return v[left]; 33 } 34 int median(vector<int> &v) { 35 // write your code here 36 return getMedian(v, 0, v.size()-1); 37 } 38 };
主要利用快排递归划分的思想,可以在期望复杂度为O(n)的条件下求第k大数。快排的期望复杂度为O(nlogn),因为快排会递归处理划分的两边,而求第k大数则只需要处理划分的一边,其期望复杂度将是O(n)。详细的证明见《算法导论》。
我们可以这样粗略的思考:
假设我们的数据足够的随机,每次划分都在数据序列的中间位置,那么第一次划分我们需要遍历约n个数,第二次需要遍历约n/2个数,...,这样递归下去,最后:n+n/2+n/(2^2)+n/(2^3)+...+n/(2^k)+... = (1+1/2+1/(2^2)+1/(2^3)+...+1/(2^k)+...)*n, 当k趋于无穷大的时候,上式的极限为2n。
[LintCode] Median(期望时间复杂度O(n)求中位数)
标签:
原文地址:http://www.cnblogs.com/pczhou/p/4684199.html