1. 程式人生 > >Top K問題——基於快速排序

Top K問題——基於快速排序

一、簡介

所謂的Top K問題其實就是找陣列中最大的前k個值。為此,只要我們能夠找到陣列中的第k大值,那麼Top K問題就會迎刃而解。在此宣告一下,本文寫的方法肯定不是最好的。不過最近看了幾個題,其核心都是找第k大的值。這裡,我只是總結下而已。

二、基本思想

1、快速排序一次;

2、利用快速排序一次的函式進行遞迴搜尋;

三、程式碼

 /*
      * p[]為待查詢陣列,L,R分別為陣列下標,k表示第k大數
      * */
       public int findKth(int[] p,int L,int R,int k){
            if
(L > R || k < 1)//檢查輸入引數是否合法 return -1; if(L == R)//如果L等於R說明已找到,直接返回 return p[R]; int temp = quickSort(p,L,R);//進行一次快排,返回下標 if(k+L == temp+1)//如果k+L等於返回的下標加1(L不一定從0開始) return p[temp];//則直接返回 if(k+L < temp+1
)//如果k+L小於返回的下標加1 return findKth(p,L,temp-1,k);//在temp的左邊查詢第k大數 else//否則,在temp的右邊部分查詢第k-(temp-L+1)大數。這裡,右邊的第 //k-(temp-L+1)大數就是整個陣列的第k大數 return findKth(p,temp+1,R,k-(temp-L+1)); } /* * 一次快速排序 *以p[L]為比較物件,比p[L]大或等於的在其左邊,否則在其右邊 */
public int quickSort(int[] p ,int L,int R){ if(L >= R) return -1; int i = L; int j = R; int temp = p[L]; while(i < j){ while(i < j && p[j] < temp) j--; if(i < j){ p[i] = p[j]; i++; } while(i < j && p[i] > temp) i++; if(i < j){ p[j] = p[i]; j--; } } p[i] = temp; //去掉以下兩句註釋,再將return註釋掉,並且將返回值改為void, //就是一個完整的快速排序 //quickSort(p ,L,i-1); //quickSort(p ,i+1,R); return i; }

三、相關習題

1、陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。

2、春節期間小明使用微信收到很多個紅包,非常開心。在檢視領取紅包記錄時發現,某個紅包金額出現的次數超過了紅包總數的一半。請幫小明找到該紅包金額。寫出具體演算法思路和程式碼實現,要求演算法儘可能高效。

給定一個紅包的金額陣列gifts及它的大小n,請返回所求紅包的金額。

測試樣例:

[1,2,3,2,2],5

返回:2

經過分析不難看出,如果解決了Top K問題,上述兩題就很容易解決了。

以上兩題來自網際網路

參考

其實,參考連結中的兩個寫的比我的好很多,呵呵呵