题目
本题目标非常简单:给定 N 个整数,找出前 K 个最大的数,并按递减序输出。
输入格式:
输入第一行给出 2 个正整数 N (≤106) 和 K (≤5)。随后一行给出 N 个整数键值,范围在区间 [−230,230] 内,以空格分隔。
输出格式:
按递减序在一行中输出前 K 个最大的数。
注意:一行中输出的数字间须以 1 个空格分隔,行首尾不得有多余空格。
输入样例 1:
10 4
40 25 60 -15 30 -21 80 -1 -5 27
输出样例 1:
80 60 40 30
输入样例 2:
4 5
23 -17 99 1
输出样例 2:
99 23 1 -17
限制
代码长度限制
16 KB
Java (javac)
时间限制
2000 ms
内存限制
300 MB
Python (python3)
时间限制
2200 ms
内存限制
5 MB
Python (python2)
时间限制
2200 ms
内存限制
5 MB
其他编译器
时间限制
150 ms
内存限制
解决方案1(Java:PriorityQueue)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Stack;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s = br.readLine().split(" ");
int N = Integer.parseInt(s[0]);
int K = Integer.parseInt(s[1]);
//s1长度为N
String[] s1 = br.readLine().split(" ");
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>( new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
for (int i = 0; i < Math.min(K,N); i++) {
priorityQueue.add(Integer.parseInt(s1[i]));
}
for (int i = K; i < N; i++) {
int num = Integer.parseInt(s1[i]);
// System.out.println("这次数字"+num);
// System.out.println("此时队列头顶为"+priorityQueue.peek());
if (num>priorityQueue.peek()){
// System.out.println("要剔除头元素了");
// System.out.println("剔除了"+));
priorityQueue.poll();
priorityQueue.add(num);
}
}
Stack<Integer> stack = new Stack<>();
while (priorityQueue.size()!=0){
stack.add(priorityQueue.remove());
}
System.out.print(stack.pop());
while (stack.size()!=0){
System.out.print(" "+stack.pop());
}
}
}
成功AC
解决方案2:不断维护一个长为K的递减数组,且这个数组的值为接收到的数里面最大的K个数
来源别人的思路,传送门:PAT 2022春季乙级 C++ 满分题解_简易测谎 c++_孟先生的思考的博客-CSDN博客
思路:初始化一个长为K的数组A,值够小。不断接收数,对于每一个接收的数X与数组A中每个数比较,一旦发现数组A中下标为i的值小于X,则什么A中0-(i-1)的数大于X,i-(A.length-1)的数小于X,故将i-(A.length-1)往右挪一挪,这样A中最小的数A[A.length-1]会被剔除,X放在i的位置,依然保持着长度K且这个K个数都是接收到的数据中的最大值。