题目描述
有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
[要求]
时间复杂度为O(klogk),空间复杂度为O(klogk)
输入描述:
第一行两个整数T, K。分别表示数组个数,需要打印前K大的元素
接下来T行,每行输入格式如下:
开头一个整数N,表示该数组的大小,接下来N个已排好序的数表示数组内的数
输出描述:
从大到小输出输出K个整数,表示前K大。
示例1
输入
3 5
5 219 405 538 845 971
2 148 558
4 52 99 348 691
输出
971 845 691 558 538
解法一:大根堆
注意:新建结构记录信息!!的做法
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] info = br.readLine().trim().split(" ");
int num = Integer.parseInt(info[0]);
int k = Integer.parseInt(info[1]);
int[][] arr = new int[num][];
for(int i=0;i<num;i++){
String[] ss = br.readLine().trim().split(" ");
arr[i] = new int[ss.length];
for(int j=0;j<ss.length;j++){
arr[i][j] = Integer.parseInt(ss[j]);
}
}
String res = getRes(arr,k);
System.out.println(res);
}
public static String getRes(int[][] arr,int k){
if(arr==null||arr.length==0) return null;
int nums = arr.length;
Heap[] heap = new Heap[nums];
for(int i=0;i<nums;i++){
int val = arr[i][arr[i].length-1];
//记录是哪一个数组,索引位置和值
Heap node = new Heap(i,arr[i].length-1,val);
heap[i] = node;
heapInsert(heap,i);
}
int heapend = heap.length-1;
StringBuilder sb = new StringBuilder();
for(int i=0;i<k;i++){
Heap node = heap[0];
sb.append(node.val+" ");
int num = node.num;
int index = node.index;
if(index>0){
heap[0] = new Heap(num,index-1,arr[num][index-1]);
heapfy(heap,heapend);
}else{
if(heapend<=0){
throw new RuntimeException("数不够");
}
heap[0] = heap[heapend];
heapfy(heap,--heapend);
}
}
return sb.toString().trim();
}
public static void heapfy(Heap[] heap,int heapend){
int left = 1;
int right = 2;
int index = 0;
int largest = index;
while(left<=heapend){
if(heap[left].val>heap[index].val){
largest = left;
}
if(right<=heapend&&heap[right].val>heap[largest].val){
largest = right;
}
if(largest!=index){
swap(heap,index,largest);
}else{
break;
}
left = largest*2+1;
right = largest*2+2;
}
}
public static void heapInsert(Heap[] heap,int index){
while(index>0){
int parent = (index-1)/2;
if(heap[parent].val<heap[index].val){
swap(heap,parent,index);
index = parent;
}else{
break;
}
}
}
public static void swap(Heap[] heap,int i,int j){
Heap tmp = heap[i];
heap[i] = heap[j];
heap[j] = tmp;
}
}
class Heap{
int num;
int index;
int val;
public Heap(int num,int index,int val){
this.num = num;
this.index = index;
this.val = val;
}
}