有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] + " "); } } }