标签:treeset 插入数据 java numbers 划分数 pivot star 查找 节点
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
对数组进行排序,从数组中取出最小的k个数。不需要对数组全部排序,只需要找出前k个数即可。
利用快速排序划分的思想,选择一个基数index
,将基数左右划分为两部分。
index > k-1
时,表示k个最小数字一定在index的左边,此时,只需要对index的左边进行划分即可index < k-1
时,说明index及index左边数字还没能满足k个数字,需要继续对k右边进行划分 public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> list = new ArrayList<Integer>(k);
if(input == null) //输入校验
return null;
if(k > input.length)
return list;
int low = 0;
int high = input.length - 1;
int index = partition(input,low,high); //划分数组,并找到基数所在的位置
while(index != k-1){
if(index > k-1){
high = index - 1; //向左划分
}else{
low = index + 1; //向右划分
}
index = partition(input,low,high); //继续划分数组,寻找基数所在位置
}
for(int i = 0; i < k; i++){
list.add(input[i]);
}
return list;
}
//划分操作
public int partition(int[] array,int start,int end){
int pivot = array[start]; //数组首位作为基数
//循环结束,将数组划分为两部分
while(start < end){
//从右向左查找,array[end] 《 pivot 的位置
while(start < end && array[end] >= pivot) end--;
//交换,放到左边
array[start] = array[end];
//从左向右查找,array[start] 》 pivot 的位置
while(start < end && array[start] <= pivot) start++;
//交换,放到右边
array[end] = array[start];
}
//start最后指向的位置 就是 基数所在位置
array[start] = pivot;
return start;
}
可以先创建一个大小为k的数据容器来存储最小的k个数字,从输入的n个整数中一个一个读入放入该容器中,如果容器中的数字少于k个,则返回null
如果容器中已有k个数字,而数组中还有值未加入,此时就不能直接插入了,而需要替换容器中的值。按以下步骤进行插入:
对于这个容器的实现,我们可以使用最大堆的数据结构,最大堆中,根节点的值大于它的子树中的任意节点值。Java中的TreeSet类实现了红黑树的功能,它底层是通过TreeMap实现的,TreeSet中的数据会按照插入数据自动升序排列(按自然顺序)。因此我们直接将数据依次放入到TreeSet中,数组就会自动排序。
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> list = new ArrayList<>();
if(input == null || k<=0 || k>input.length) return list; //输入校验
TreeSet<Integer> set = new TreeSet<>();
for(int i=0;i<input.length;i++){
set.add(input[i]); //数组元素添加入set
}
int i=0;
//取出前k个值
for(Integer item : set){
if(i >= k) break;
list.add(item);
i++;
}
return list;
}
标签:treeset 插入数据 java numbers 划分数 pivot star 查找 节点
原文地址:https://www.cnblogs.com/le-le/p/12728537.html