[LintCode] Median(期望時間復雜度O(n)求中位數和第k大數)


 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 getMinK(vector<int> &v, int left, int right, int k)
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             if(k==i+1)  return v[i+1];
28             else if(k<=i)   return getMinK(v, left, i, k);
29             else return getMinK(v, i+2, right, k);
30         }
31         else    return v[left];
32     }
33     int median(vector<int> &v) {
34         // write your code here
35         return getMinK(v, 0, v.size()-1, (v.size()-1)/2);
36     }
37 };

主要利用快排遞歸划分的思想,可以在期望復雜度為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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM