码迷,mamicode.com
首页 > 其他好文 > 详细

[LintCode] Median(期望时间复杂度O(n)求中位数)

时间:2015-07-28 20:56:15      阅读:1220      评论:0      收藏:0      [点我收藏+]

标签:

 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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!