对于一个无序数组,数组中元素为互不相同的整数,请返回其中最小的k个数,顺序与原数组中元素顺序一致。
给定一个整数数组A及它的大小n,同时给定k,请返回其中最小的k个数。
测试样例:
[1,2,4,3],4,2
返回:[1,2]
第一种方式:利用堆排序
import java.util.*;
public class KthNumbers {/*分析:先找到最大的第k个数 遍历原数组比k小的输出即可
* 利用优先级队列实现堆排序
* 现将前k个数存入队列中
* 然后从k+1~n遍历 和队列中最大的比较 如果小于最大值 说明这个数在k个数中 将最大值出列 将这个值加入队列
* 遍历结束 得到k个数中的最大值 遍历原数组将比最大值小的输出*/
public int[] findKthNumbers(int[] A, int n, int k) {
PriorityQueue<Integer> priorityQueu = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
@Override
public int compare(Integer lhs, Integer rhs) {
return rhs-lhs;
}
});
for (int i = 0; i < n; i++) {
if (priorityQueu.size()<k){
Integer x = A[i];
priorityQueu.offer(x);
continue;
}
if (A[i]<=priorityQueu.peek()){
Integer x = A[i];
priorityQueu.poll();
priorityQueu.offer(x);
}
}
int[] res = new int[k];
int j=0;
for (int i = 0; i < n; i++) {
if(priorityQueu.peek()>=A[i]){
res[j] = A[i];
j++;
}
}
return res;
}
}
第二种方式:利用快排的思想 找到第k大的数
public int[] findKthNumbers(int[] A, int n, int k) { int[] B = Arrays.copyOf(A,A.length); int[] res = new int[k]; int i = 0; int max = quickfind(B,0,B.length-1,k-1); System.out.println("max:"+max); for (int x : A) { if (max >= x) { System.out.print(x+" "); res[i] = x; i++; } } return res; } public int quickfind(int[] A,int start,int end,int target){ int low = start; int high = end; int key = A[low]; while(low<high){ while(low<high&&key<=A[high]){ high--; } A[low] = A[high]; while(low<high&&key>=A[low]){ low++; } A[high] = A[low]; } A[low] = key; if(low>target){ return quickfind(A,start,high-1,target); } if (low<target){ return quickfind(A,low+1,end,target); } System.out.println("low:" + low); return A[low]; }
题目来源:http://www.nowcoder.com/practice/ec2575fb877d41c9a33d9bab2694ba47?rp=2&ru=/activity/oj&qru=/ta/2016test/question-ranking