问题来自牛客剑指offer
题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
问题思路
利用排序:最直观的我觉得就是选择排序,因为选择排序是按照每次固定一个数的思路来的,我们将外层控制排列轮数的值改为K即可。利用堆结构(巧妙)利用堆(java中的PriorityQueue)先存储K个元素,形成一个大根堆。之后每次新来的数都和堆顶比较,如果大于堆顶:那么这个数一定不是前K个最小的数,如果小于堆顶,就把堆顶的数弹出,并把新的数压入。一次遍历完整个数组就可以得到前K个最小的数。
Code
public ArrayList
<Integer> GetLeastNumbers_Solution(int[] input
, int k
) {
ArrayList
<Integer> array
= new ArrayList();
if (k
> input
.length
) return array
;
for (int i
= 0; i
< k
; i
++) {
int min
= i
;
for (int j
= i
; j
< input
.length
; j
++) {
if (input
[j
] < input
[min
]) min
= j
;
}
int temp
= input
[i
];
input
[i
] = input
[min
];
input
[min
] = temp
;
array
.add(input
[i
]);
}
return array
;
}
public ArrayList
<Integer> GetLeastNumbers_Solution(int[] input
, int k
) {
ArrayList
<Integer> array
= new ArrayList();
if (input
.length
< k
|| input
.length
== 0 || k
== 0) return array
;
PriorityQueue
<Integer> priorityQueue
= new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1
, Integer o2
) {
return o2
- o1
;
}
});
for (int i
= 0; i
< k
; i
++) {
priorityQueue
.add(input
[i
]);
}
for (int i
= k
; i
< input
.length
; i
++) {
if (priorityQueue
.peek() < input
[i
]) continue;
else {
priorityQueue
.poll();
priorityQueue
.add(input
[i
]);
}
}
for (Integer item
: priorityQueue
) {
array
.add(item
);
}
return array
;
}