1. 问题: 从一个无序的数组中找出中位数
  • 这个类似于topk的问题,可以跟topK问题一起解决
  1. 解法:1.可以使用小顶堆,堆的大小为数组的一半,遍历一遍以后,输出堆顶元素即可。2.使用快排+二分,找一个基数,通过快排的方式将数组(长度为n)划分为两部分,如果恰好两部分的长度相等(=(n-1)/2,),则中位数就是当前基数,如果左边长度小于(n-1)/2,那中位数就在右侧。反之在左侧。

​快排思想求解TOPK​​ 3. 代码:

public class One {

public static int getMid1(int[] nums,int k){
int n= nums.length;
int queueLength =k;
Queue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
for (int i = 0; i <n ; i++) {
if (queue.size()<queueLength){
queue.add(nums[i]);
}else {
int temp =queue.peek();
if (nums[i]>temp){
queue.poll();
queue.add(nums[i]);
}
}
}
return queue.peek();
}

public static void quickSort(int[] nums,int low ,int high){
if (low>=high){
return;
}
int temp = nums[low];
int i=low;
int j=high;
while (i<j){
while (i<j && nums[j]>=temp){
j--;
}
if (i<j){
nums[i]=nums[j];
i++;
}
while (i<j && nums[i]<=temp){
i++;
}
if (i<j){
nums[j]=nums[i];
j--;
}
}
nums[i]=temp;
quickSort(nums,low,i-1);
quickSort(nums,i+1,high);
}
public static int PartSort(int[] nums,int start ,int end){
int left =start;
int right =end;
int temp = nums[left];
while (left<right){
while (left<right && nums[right]>=temp){
right--;
}
if (left<right){
nums[left]=nums[right];
left++;
}
while (left<right && nums[left]<=temp){
left++;
}
if (left<right){
nums[right]= nums[left];
right--;
}
}
nums[left]=temp;
return left;
}
public static int getMid2(int[] nums,int low ,int high ,int k){
int p =PartSort(nums,low,high);
if (k==p-low+1){
return nums[p];
}else if (k - 1 < p - low){//则第k大的元素在前半段
return getMid2(nums,low,p-1,k);
}else {
return getMid2(nums, p+1, high, k-1+low-p);
}
}



public static void main(String[] args) {

int[] nums =new int[]{5,3,2,1,6,9,7,10,-1,-2,11};
System.out.println(getMid2(nums,0, nums.length-1, (nums.length+1)/2));
System.out.println(getMid1(nums,(nums.length+1)/2));

}

}