有N个长度不一的数组,所有的数组都是有序的,请从大到小打印这N个数组整体最大的前K个数。
例如,输入含有N行元素的二维数组可以代表N个一维数组。
219, 405, 538, 845, 971
148, 558
52, 99, 348, 691
再输入整数k=5,则打印:
Top 5: 971, 845, 691, 558, 538
[要求]
时间复杂度为
,空间复杂度为
第一行两个整数T, K。分别表示数组个数,需要打印前K大的元素
接下来T行,每行输入格式如下:
开头一个整数N,表示该数组的大小,接下来N个已排好序的数表示数组内的数
从大到小输出输出K个整数,表示前K大。
3 5 5 219 405 538 845 971 2 148 558 4 52 99 348 691
971 845 691 558 538
保证各个输入值合法
if (m == 1)// m表示读取一行数据split后得到的数组长度。
throw new RuntimeException("cnm"); 终于找到问题了。不是在备注里写明了数组内总个数大于1。你备注个是个锤子。我现在看到牛客报数组越界或非法访问就恶心。 import java.io.*;
import java.util.PriorityQueue;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] s = reader.readLine().split(" ");
int n = Integer.valueOf(s[0]);
int k = Integer.valueOf(s[1]);
int[][] arr = new int[n][];
for (int i = 0; i < n; i++) {
String[] str = reader.readLine().split(" ");
int m = str.length;
arr[i] = new int[m - 1];
for (int j = 0; j < m - 1; j++) {
arr[i][j] = Integer.valueOf(str[j + 1]);
}
}
PriorityQueue<Tuple> maxHeap = new PriorityQueue<>((o1, o2) -> o2.val - o1.val);
for (int i = 0; i < n; i++) {
int len = arr[i].length;
//在这里设置 len==0,直接continue,就是能ac的代码。 //if(len == 0) continue;
maxHeap.offer(new Tuple(i, len - 1, arr[i][len - 1]));
}
StringBuilder res = new StringBuilder();
for (int j = 0; j < k; j++) {
Tuple temp = maxHeap.poll();
res.append(temp.val).append(" ");
if (temp.index > 0) {
maxHeap.add(new Tuple(temp.line, temp.index - 1, arr[temp.line][temp.index - 1]));
}
}
System.out.println(res);
}
static class Tuple {
int line;
int index;
int val;
Tuple(int line, int index, int val) {
this.line = line;
this.index = index;
this.val = val;
}
}
} import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] s = reader.readLine().split(" ");
int n = Integer.valueOf(s[0]);
int k = Integer.valueOf(s[1]);
int[][] arr = new int[n][];
for (int i = 0; i < n; i++) {
String[] str = reader.readLine().split(" ");
int m = str.length;
arr[i] = new int[m];
for (int j = 0; j < m; j++) {
arr[i][j] = Integer.valueOf(str[j]);
}
}
PriorityQueue<Tuple> maxHeap = new PriorityQueue<>((o1, o2) -> o2.val - o1.val);
for (int i = 0; i < n; i++) {
int len = arr[i].length;
maxHeap.offer(new Tuple(i, len - 1, arr[i][len - 1]));
}
StringBuilder res = new StringBuilder();
for (int j = 0; j < k; j++) {
Tuple temp = maxHeap.poll();
res.append(temp.val).append(" ");
if (temp.index > 1) {
maxHeap.add(new Tuple(temp.line, temp.index - 1, arr[temp.line][temp.index - 1]));
}
}
System.out.println(res);
}
static class Tuple {
int line;
int index;
int val;
Tuple(int line, int index, int val) {
this.line = line;
this.index = index;
this.val = val;
}
}
} import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.PriorityQueue;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] params = br.readLine().split(" ");
int t = Integer.parseInt(params[0]), k = Integer.parseInt(params[1]);
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
while(t-- > 0){
params = br.readLine().split(" ");
int n = Integer.parseInt(params[0]);
int[] arr = new int[n];
for(int i = 0; i < n; i++){
int num = Integer.parseInt(params[i + 1]);
if(minHeap.size() < k){
minHeap.offer(num);
}else{
if(minHeap.peek() < num){
minHeap.poll();
minHeap.offer(num);
}
}
}
}
int[] res = new int[k];
for(int i = k - 1; i >= 0; i--) res[i] = minHeap.poll();
for(int i = 0; i < k; i++) System.out.print(res[i] + " ");
}
} #include <bits/stdc++.h>
using namespace std;
int main(){
int T,K,n,x;
cin>>T>>K;
priority_queue<int, vector<int>, greater<int>> q;
for(int i=0;i<T;i++){
cin>>n;
for(int j=0;j<n;j++){
cin>>x;
if(q.size() < K)
q.push(x);
else{
q.pop();
q.push(x);
}
}
}
int l = q.size();
int a[l];
for(int i=0;i<l;i++){
a[l-i-1] = q.top();
q.pop();
}
for(int i=0;i<l;i++)
cout<<a[i]<<" ";
return 0;
} #include<bits/stdc++.h>
using namespace std;
priority_queue<int, vector<int>, greater<int> > pq;
// 递归打印
void print() {
if (pq.empty()) return;
int val = pq.top();
pq.pop();
print();
printf("%d ", val);
}
int main() {
int T, K;
scanf("%d%d", &T, &K);
int len = 0;
int x = 0;
int psize = 0; //记录最小堆的大小
while (T--) {
scanf("%d", &len);
while (len--) {
scanf("%d", &x);
if (psize < K) {
psize++;
pq.push(x);
} else {
pq.pop();
pq.push(x);
}
}
}
print();
return 0;
}
#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
class HeapNode{
public:
int val;
int arrayId;
HeapNode(int v,int arrId):val(v),arrayId(arrId){}
bool operator<(const HeapNode& another)const{
return val < another.val;
}
};
int main() {
int T,K;
cin >> T >> K;
vector<vector<int>> arrs(T);
for(int i = 0;i < T;i++){
int n = 0;
cin >> n;
arrs[i].resize(n);
for(int j = 0;j < n;j++){
cin >> arrs[i][j];
}
}
priority_queue<HeapNode> heap;
for(int i = 0;i < T;i++){
if(arrs[i].empty()) continue;
heap.push(HeapNode(arrs[i].back(),i));
arrs[i].pop_back();
}
for(int i = 0;i < K;i++){
cout << heap.top().val << " ";
int arrId = heap.top().arrayId;
heap.pop();
if(arrs[arrId].empty()) continue;
heap.push(HeapNode(arrs[arrId].back(),arrId));
arrs[arrId].pop_back();
}
}
C++利用STL库实现的堆容器的实现
import java.util.*;
//记录加入堆中的每一个数来自哪个数组,值,与位置
class HeapNode {
public int val;
public int arrNum;
public int index;
public HeapNode(int v, int a, int i) {
this.val = v;
this.arrNum = a;
this.index = i;
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int[][] m = new int[n][];
for (int i = 0; i < n; i++) {
int n2 = sc.nextInt();
int[] arr = new int[n2];
for (int j = 0; j < n2; j++) {
arr[j] = sc.nextInt();
}
m[i] = arr;
}
int[] res = getTopK(m, k);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < res.length; i++) {
sb.append(res[i] + " ");
}
System.out.println(sb.toString());
sc.close();
}
//建一个长度为n的大根堆,最开始装所有数组的最后位置(因为是有序数组),
//然后把头弹出,必为所有数的最大值。然后找第二大的数时,前一个是从
//哪个数组弹出的,就把弹出位置的前一个数也就是arr[len-2]加进大根堆
//头,用heapify,以此类推.
//若某一弹出数为该数组的第一个位置,则置换其与最后一个数,同时有效长度--。
public static int[] getTopK(int[][] m, int k) {
//长度为n的大根堆
int validArrNum = 0;
int len = 0;
//防止k比总数量大,或者某一行长度为0
for (int i = 0; i < m.length; i++) {
if (m[i] != null && m[i].length != 0)
validArrNum++;
len += m[i].length;
}
HeapNode[] heap = new HeapNode[validArrNum];
len = len <= k ? len : k;
int[] res = new int[len];
int heapI = 0;
for (int i = 0; i < m.length; i++) {
if (m[i] == null || m[i].length == 0)
continue;
int index = m[i].length-1;
heap[heapI] = new HeapNode(m[i][index], i, index);
heapInsert(heap, heapI++);
}
int size = validArrNum;
for (int i = 0; i < len; i++) {
res[i] = heap[0].val;
int arrNum = heap[0].arrNum;
int index = heap[0].index;
if (index > 0) {
heap[0] = new HeapNode(m[arrNum][index-1], arrNum, index-1);
heapify(heap, 0, size);
}
else {
heap[0] = heap[heap.length-1];
heapify(heap, 0, --size);
}
}
return res;
}
public static void heapInsert(HeapNode[] arr, int i) {
while (arr[(i-1)/2].val < arr[i].val) {
swap(arr, (i-1)/2, i);
i = (i-1)/2;
}
}
public static void swap(HeapNode[] arr, int i, int j) {
HeapNode tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void heapify (HeapNode[] arr, int i, int size) {
int left = 2 * i + 1;
int right = 2 * i + 2;
int maxI = 0;
while (left < size) {
maxI = left;
if (right < size)
maxI = arr[left].val < arr[right].val ? right : maxI;
maxI = arr[maxI].val < arr[i].val ? i : maxI;
if (maxI == i)
break;
swap(arr, i, maxI);
i = maxI;
left = 2 * i + 1;
right = 2 * i + 2;
}
}
} import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
int[][] arr=new int[n][];
int[] pos=new int[n];
int k=sc.nextInt();
for(int i=0;i<n;i++){
int tmp=sc.nextInt();
int[] A=new int[tmp];
pos[i]=tmp-1;
for(int j=0;j<tmp;j++){
A[j]=sc.nextInt();
}
arr[i]=A;
}
solve(arr,pos,k);
}
sc.close();
}
public static void solve(int[][] arr,int[] pos,int k) {
StringBuilder sb=new StringBuilder();
for(int i=0;i<k;i++) {
int tmp=arr[0][pos[0]];
int index=0;
for(int j=1;j<arr.length;j++) {
if(pos[j]>0&&arr[j][pos[j]]>tmp) {
tmp=arr[j][pos[j]];
index=j;
}
}
pos[index]--;
sb.append(tmp).append(" ");
}
System.out.println(sb.toString().trim());
}
} #include <cstdio>
(802)#include <cstring>
#include <algorithm>
(831)#include <iostream>
#include <string>
(765)#include <vector>
#include <stack>
(850)#include <bitset>
#include <cstdlib>
(895)#include <cmath>
#include <set>
(855)#include <list>
#include <deque>
(2572)#include <map>
#include <queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
const int maxn = 100;
struct HeapNode
{
int val;
int row;
int col;
bool operator<(const HeapNode &a) const
{
return this->val < a.val;
}
bool operator>(const HeapNode &a) const
{
return this->val > a.val;
}
};
int main()
{
int t, k;
scanf("%d%d\n", &t, &k);
vector<vector<int>> arr2d;
for (int i = 0; i < t; i++)
{
int n;
scanf("%d", &n);
vector<int> arr;
for (int j = 0; j < n; j++)
{
int val;
scanf("%d", &val);
arr.push_back(val);
}
arr2d.push_back(arr);
}
priority_queue<HeapNode, vector<HeapNode>> queue;
for (int i = 0; i < t; i++)
{
if (!arr2d[i].empty())
{
HeapNode node;
node.val = arr2d[i].back();
node.row = i;
node.col = arr2d[i].size() - 1;
queue.push(node);
}
}
for (int i = 0; i < k; i++)
{
HeapNode node = queue.top();
cout << node.val << " ";
if (node.col > 0)
{
HeapNode next;
next.val = arr2d[node.row][node.col -1];
next.row = node.row;
next.col = node.col - 1;
queue.pop();
queue.push(next);
}
else
{
queue.pop();
}
}
cout << endl;
return EXIT_SUCCESS;
} import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int k = scanner.nextInt();
PriorityQueue<Integer> queue = new PriorityQueue<>((n1,n2)->n1-n2) ;
for(int i=0;i<n;i++) {
int p = scanner.nextInt();
for(int j=0;j<p;j++) {
queue.add(scanner.nextInt());
if(queue.size()>k) {
queue.poll();
}
}
}
int[] arr = new int[k];
for(int i=0;i<k;i++) {
arr[i] = queue.poll();
}
for(int i=k-1;i>=0;i--) {
System.out.print(arr[i] + " ");
}
}
}