【面試題】給多個無序正整數,求中位數
阿新 • • 發佈:2018-12-10
題目:給你很多很多正整數,但它們是無序的,找出它們的中位數。
最開始就想說使用快排,先將這些整數進行排序,然後找到中位數,但又想到可能不是面試官想要的答案,於是又採用了其他方法,最終也沒完全解決出來。
【經驗總結:當面試官問了一個演算法題後,如果想不到優化一點的方法,就先把能想到的解決方案告訴他,即使這種方案可能很爛[笑哭],然後再考慮下一步的優化,不要總想著一下就能找到最優的解法,這樣最終可能啥也說不出來。】
思路:這題比較好的方法是採用堆,用序列的前(n+1)/2個數建立一個最小堆,然後繼續往後遍歷,並將每個數與堆頂元素進行比較,如果小於等於堆頂元素,忽略,遍歷下一個,如果大於堆頂元素,則將堆頂元素用當前遍歷到的元素替換,然後重新調整為最小堆,遍歷完成後,堆頂元素即為中位數。 一直保證堆頂是第k小的元素,遍歷完成後,堆頂就成了第(n+1)/2小的元素,即為中位數。
程式碼:
public class Mid { public static void main(String[] args) { int[] num = {5,7,6,3,8,1,4}; int n = getMid(num); System.out.println(n); } private static int getMid(int[] num) { int len =(num.length+1)/2; for(int i=len/2;i>=0;i--) adjustHeap(num,i,len-1); System.out.println(Arrays.toString(num)); for (int j = len; j<num.length; j++) { if(num[j]>num[0]) { num[0]=num[j]; adjustHeap(num,0,len-1); } } return num[0]; } private static void adjustHeap(int[] num, int i, int j) { int tmp = num[i]; for (int k = 2*i+1; k <=j; k++) { if(k<j&&num[k]>num[k+1]) k++; if(num[k]<tmp) { num[i]=num[k]; i=k; }else break; } num[i]=tmp; } private static void swap(int[] num, int i, int j) { int tmp=num[i]; num[i]=num[j]; num[j]=tmp; } }
輸出: