1. 程式人生 > >【面試題】給多個無序正整數,求中位數

【面試題】給多個無序正整數,求中位數

題目:給你很多很多正整數,但它們是無序的,找出它們的中位數。

最開始就想說使用快排,先將這些整數進行排序,然後找到中位數,但又想到可能不是面試官想要的答案,於是又採用了其他方法,最終也沒完全解決出來。

【經驗總結:當面試官問了一個演算法題後,如果想不到優化一點的方法,就先把能想到的解決方案告訴他,即使這種方案可能很爛[笑哭],然後再考慮下一步的優化,不要總想著一下就能找到最優的解法,這樣最終可能啥也說不出來。】

思路:這題比較好的方法是採用堆,用序列的前(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;
	}
}

輸出: