在不少的筆試和麪試中,喜歡考察Top K.下面從自身的經驗給出三種實現方式及實用範圍。java
這種方法適用於幾個數組有序的狀況,來求Top k。時間複雜度爲O(k*m)。(m:爲數組的個數).具體實現以下:面試
/** * 已知幾個遞減有序的m個數組,求這幾個數據前k大的數 *適合採用Merge的方法,時間複雜度(O(k*m); */ import java.util.List; import java.util.Arrays; import java.util.ArrayList; public class TopKByMerge{ public int[] getTopK(List<List<Integer>>input,int k){ int index[]=new int[input.size()];//保存每一個數組下標掃描的位置; int result[]=new int[k]; for(int i=0;i<k;i++){ int max=Integer.MIN_VALUE; int maxIndex=0; for(int j=0;j<input.size();j++){ if(index[j]<input.get(j).size()){ if(max<input.get(j).get(index[j])){ max=input.get(j).get(index[j]); maxIndex=j; } } } if(max==Integer.MIN_VALUE){ return result; } result[i]=max; index[maxIndex]+=1; } return result; }
快排過程法利用快速排序的過程來求Top k.平均時間複雜度爲(O(n)).適用於無序單個數組。具體java實現以下:數組
/* *利用快速排序的過程來求最小的k個數 * */ public class TopK{ int partion(int a[],int first,int end){ int i=first; int main=a[end]; for(int j=first;j<end;j++){ if(a[j]<main){ int temp=a[j]; a[j]=a[i]; a[i]=temp; i++; } } a[end]=a[i]; a[i]=main; return i; } void getTopKMinBySort(int a[],int first,int end,int k){ if(first<end){ int partionIndex=partion(a,first,end); if(partionIndex==k-1)return; else if(partionIndex>k-1)getTopKMinBySort(a,first,partionIndex-1,k); else getTopKMinBySort(a,partionIndex+1,end,k); } } public static void main(String []args){ int a[]={2,20,3,7,9,1,17,18,0,4}; int k=6; new TopK().getTopKMinBySort(a,0,a.length-1,k); for(int i=0;i<k;i++){ System.out.print(a[i]+" "); } } }
求最大K個採用小根堆,而求最小K個採用大根堆。大數據
求最大K個的步奏:this
求最小K個跟這求最大K個相似。時間複雜度O(nlogK)(n:數據的長度),特別適用於大數據的求Top K。spa
/** * 求前面的最大K個 解決方案:小根堆 (數據量比較大(特別是大到內存不能夠容納)時,偏向於採用堆) * * */ public class TopK { /** * 建立k個節點的小根堆 * * @param a * @param k * @return */ int[] createHeap(int a[], int k) { int[] result = new int[k]; for (int i = 0; i < k; i++) { result[i] = a[i]; } for (int i = 1; i < k; i++) { int child = i; int parent = (i - 1) / 2; int temp = a[i]; while (parent >= 0 &&child!=0&& result[parent] >temp) { result[child] = result[parent]; child = parent; parent = (parent - 1) / 2; } result[child] = temp; } return result; } void insert(int a[], int value) { a[0]=value; int parent=0; while(parent<a.length){ int lchild=2*parent+1; int rchild=2*parent+2; int minIndex=parent; if(lchild<a.length&&a[parent]>a[lchild]){ minIndex=lchild; } if(rchild<a.length&&a[minIndex]>a[rchild]){ minIndex=rchild; } if(minIndex==parent){ break; }else{ int temp=a[parent]; a[parent]=a[minIndex]; a[minIndex]=temp; parent=minIndex; } } } int[] getTopKByHeap(int input[], int k) { int heap[] = this.createHeap(input, k); for(int i=k;i<input.length;i++){ if(input[i]>heap[0]){ this.insert(heap, input[i]); } } return heap; } public static void main(String[] args) { int a[] = { 4, 3, 5, 1, 2,8,9,10}; int result[] = new TopK().getTopKByHeap(a, 3); for (int temp : result) { System.out.println(temp); } } }