如何找N個數中第i小的數

  聽說這是面試算法崗位中最常問的問題,各個面經裏面出現這個問題的比率很高,今天的算法課講了《算法導論》的第九章「中位數和順序統計量」,9.2和9.3偏偏介紹的就是這個問題,這裏作一下總結,說一下本身的理解。面試

  首先,接手這個問題最直接的想法莫過於排序了,經常使用的排序算法裏面有冒泡排序、選擇排序、插入排序、歸併排序、堆排序、快速排序、計數排序、基數排序、桶排序等,雖說快排的平均時間複雜度達到了O(nlgn),桶排序的平均時間複雜度達到了O(n)可是基於排序的方法對於這個問題並非一個好的解決方法。O(nlgn)的排序就不說了,O(n)的排序前面隱含的常數因子也會被下面介紹的算法所戰勝。算法

  接下來會想到的方法,多是對整個數組過i遍,每次都選擇最小的,這樣第i次就選到了第i小的,這樣的話時間複雜度就成了O(in),當i比較大時,仍然是不可接受的,萬一i接近n/2呢,豈不是都O(n2)了。數組

  指望線性時間複雜度算法spa

  思考一下快排的PARTITION過程,通過屢次左右互換,實現了針對於選定靶點A[q],左側的元素都小於A[q],右側的元素都大於A[q]。這個過程豈不是能用來幫助選點。code

                                               

 1 RANDOMIZED-SELECT(A,p,r,i)
 2     if p==r
 3         return A[p]
 4     q = RANDOMIZED-PARTITION(A,p,r)    //劃分位置
 5     k = q-p+1
 6     if i==k           //the pivot value is the answer
 7         return A[q]
 8     else if i<k
 9         return RANDOMIZED-SELECT(A,p,q-1,i)
10     else return RANDOMIZED-SELECT(A,q+1,r,i-k)

第4行的劃分位置是隨機取到的,這樣就爲下面分析其指望時間複雜度埋下伏筆。k是left部分的長度。當i=k時,六、7行是k恰好知足長度要求,程序結束。第9行,意思是i<k時,程序進入left部分(注意遞歸處理的數組的範圍的變化爲A[p]~A[q-1]);當i>k時,進入right部分(注意遞歸處理的數組的範圍的變化爲A[q+1]~A[r],尋找的數的「位置」也要減去left部分的長度)。如此遞歸下去,則總會退出,即找到對應的第i小的數。blog

  下面分析其時間複雜度。排序

  最壞狀況:假如第4行的RANDOMIZED-PARTITION(A,p,r) 每次劃分的比例都是0:n-1(即最差狀況),這樣的話時間複雜度就是O(n2)。遞歸

  平均狀況:T(n)≤Σk=1nXk•(T(max(k-1,n-k))+O(n) ) = Σk=1nXk•T(max(k-1,n-k)) + O(n) class

    通過替換推導 E(T(n)) ≤ cn。即指望時間複雜度爲線性時間複雜度。程序

 

 

  最壞狀況爲線性時間點的選擇算法

  該算法比「指望線性時間複雜度算法」的主要改進是經過尋找中位數來獲得一個更好的劃分(上面的是隨機取的劃分位置)。SELECT算法使用的也是快速排序的肯定性劃分算法PARTITION,但作了修改,把劃分的主元也做爲輸入參數。

經過執行下列步驟,算法SELECT能夠肯定一個有n>1個不一樣的元素的輸入數組中第i小的元素。(若是n=1,則SEKECT只返回它的惟一輸入數值做爲第i小的元素 )
(1)將輸入數組的n個元素劃分爲(n/5)組,每組5個元素,且至多隻有一組由剩下的n mod 5個元素組成。
(2)尋找這(n/5)組中每一組中位數:首先對每組元素進行插入排序,而後肯定每組有序元素的中位數。
(3)對第2步中找出的(n/5)箇中位數,遞歸調用SELECT以找出其中位數x(若是有偶數箇中位數,爲了方便,約定x是較小的中位數)
(4)利用修改過的PARTITION版本,按中位數的中位數x對輸入數組進行劃分。令k=劃分的低區中的元素個數+1,所以x是第k小的元素,而且有n-k個元素在劃分的高區。
(5)若是i=k,則返回x。若是i<k,則在低區遞歸調用SELECT來找出第i小的元素。若是i>k,則高區遞歸查找第i-k小的元素。

步驟一、2和4須要O(n)的時間。(步驟2是對大小爲O(1)的集合調用O(n)次插入排序) 步驟3所需時間爲T(n/5),步驟5所需時間至多爲T(7n/10+6)(具體推導請參考算導9.3)。這樣根據主方法就很容易推導出時間複雜度爲線性。(T(n)≤cn)

相關文章
相關標籤/搜索