【面试题】给多个无序正整数,求中位数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Somnus_k/article/details/82724011

题目:给你很多很多正整数,但它们是无序的,找出它们的中位数。

最开始就想说使用快排,先将这些整数进行排序,然后找到中位数,但又想到可能不是面试官想要的答案,于是又采用了其他方法,最终也没完全解决出来。

【经验总结:当面试官问了一个算法题后,如果想不到优化一点的方法,就先把能想到的解决方案告诉他,即使这种方案可能很烂[笑哭],然后再考虑下一步的优化,不要总想着一下就能找到最优的解法,这样最终可能啥也说不出来。】

思路:这题比较好的方法是采用堆,用序列的前(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;
	}
}

输出:

猜你喜欢

转载自blog.csdn.net/Somnus_k/article/details/82724011