输入一个长度为 n 的整数数列,从小到大输出前 m 小的数。
输入格式
第一行包含整数 n 和 m。
第二行包含 n 个整数,表示整数数列。
输出格式
共一行,包含 m 个整数,表示整数数列中前 m 小的数。
数据范围
1≤m≤n≤105,
1≤数列中元素≤109
输入样例:
5 3
4 5 1 3 2
输出样例:
1 2 3
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Created with IntelliJ IDEA.
*
* @Auther: zlf
* @Date: 2021/04/17/20:55
* @Description: 堆排序 每次输出最小的 这是小顶堆
*/
public class Main {
/**
对于二叉树堆来说,用层次遍历(左到右)的存储来讲 如果一个节点在数组中的下标是 n 那左节点就是 2*n 右节点 2*n+1
*/
static int size = 0;
public static void swap(int h[],int i,int j){
int t = h[i];
h[i] = h[j];
h[j] = t;
}
public static void down(int u,int h[]){
int t = u;
// 与左右儿子进行比较
if(u*2 <= size && h[u*2] < h[t]) t = u*2;
if(u*2+1<= size && h[u*2+1] < h[t]) t = u*2+1;
// 交换
if(t!=u){
swap(h,u,t);
// 接着向下比较
down(t,h);
}
}
public static void up(int u,int h[]){
// u/2 > 0 判断父节点是否存在 如果存在,父节点大于子节点就交换
while(u/2>0 && h[u/2] > h[u]){
swap(h,u,u/2);
u/=2;
}
}
public static void main(String[] args) throws IOException {
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
String []s = read.readLine().split(" ");
int n = Integer.valueOf(s[0]).intValue();
int m = Integer.valueOf(s[1]).intValue();
String[] str = read.readLine().split(" ");
int h[] = new int[str.length+1];
for (int i = 1; i <= n; i++) {
h[i] = Integer.valueOf(str[i-1]).intValue();
}
size = n;
for (int i=n/2;i>=0;i--) down(i,h);
while (m-->0){
down(1,h);
System.out.print(h[1]+" ");
// 将最小值删除 只需要用末尾元素替换即可
h[1] = h[size];
size--;
// 重新向下比较
down(1,h);
}
}
}
579

被折叠的 条评论
为什么被折叠?



