JZ29 最小的K个数
题目描述:
给定一个数组,找出其中最小的K个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。如果K>数组的长度,那么返回一个空的数组
示例:
输入:
[4,5,1,6,2,7,3,8],4
返回值:
[1,2,3,4]
题解:
方法一:排序
1.思路:
思路很简单,直接将所给的数组排序,直接返回前k个值。
可以用java所给的sort 函数
2.复杂度:
时间复杂度:O(nlongn)
空间复杂度:O(1)
3.代码:
import java.util.*;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
// 方法一:排序
ArrayList<Integer> array = new ArrayList<>();
if(input.length<k)
return array;
Arrays.sort(input);
for(int i=0; i<k; i++){
array.add(input[i]);
}
return array;
}
}
}
方法二:优先队列
1.思路:
可以利用优先队列的特性,可以直接更新容量为k的队列中的值,只需遍历一次题目所给的数组就可以将其中最小的k个值获取出来。
注意优先队列其实是利用大根堆进行插入。
2.复杂度:
时间复杂度:O(nlongk), 更新一次优先队列时间复杂度为O(longk), 一共遍历n个元素
空间复杂度:O(k)
3.代码:
import java.util.*;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
// 方法二:优先队列
ArrayList<Integer> array = new ArrayList<>();
if(k>input.length || k==0)
return array;
//定义优先队列从大到小排列
PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>(){
@Override
public int compare(Integer i1,Integer i2){
return i2-i1;
}
});
for(int i=0; i<k; i++){
queue.add(input[i]);
}
for(int i=k; i<input.length; i++){
if(queue.peek()>input[i]){
queue.poll();
queue.add(input[i]);
}
}
for(int i=0; i<k; i++){
array.add(queue.poll());
}
return array;
}
}
}
方法二:快排思想
1.思路:
想一下快排的基本思路是什么?
对数组[left,right]进行一次快排之后,将数组分为 [lleft,mid-1],mid,[mid+1,right]三个区间;
其中[lleft,mid-1]区间的数值都小于坐标为mid的值,如果mid==k时说明最小的k个数为坐标 [lleft,mid-1],mid所对应的值。
2.复杂度:
时间复杂度:平均时间复杂度为O(n)
空间复杂度:O(1)
3.代码:
import java.util.*;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
// 方法三:快排思想
ArrayList<Integer> array = new ArrayList<>();
if(k>input.length || k==0)
return array;
quickSort(input, 0, input.length-1, k-1, array);
return array;
}
void quickSort(int[] input, int left, int right, int k, ArrayList<Integer> array ){
int start = left;
int end = right;
while(start < end){
while(start<end && input[left] <= input[end]) end--;
while(start<end && input[left] >= input[start]) start++;
int temp = input[start];
input[start] = input[end];
input[end] = temp;
}
int temp = input[left];
input[left] = input[start];
input[start] =temp;
if(start < k){
quickSort(input, start+1, right, k, array);
}else if(start > k){
quickSort(input, left, start-1, k, array);
}else{
for(int i=0; i<=k; i++){
array.add(input[i]);
}
}
}
}