题解 | #两个有序数组间相加和的Topk问题#
两个有序数组间相加和的Topk问题
https://www.nowcoder.com/practice/7201cacf73e7495aa5f88b223bbbf6d1
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt(), k = in.nextInt();
int[] arr1 = new int[n], arr2 = new int[n];
for (int i = 0; i < n; i++) arr1[i] = in.nextInt();
for (int i = 0; i < n; i++) arr2[i] = in.nextInt();
int[] topK = topKsum(arr1, arr2, Math.min(k, 2 * n));
for (int x : topK) System.out.print(x + " ");
System.out.println();
in.close();
}
private static int[] topKsum(int[] arr1, int[] arr2, int k) {
int[] ans = new int[k];
// 创建一个大根堆,每次存储arr1[i] + arr2[j] 的位置和值,每次从堆顶取数
Queue<Node> maxHeap = new PriorityQueue<>((o1, o2) -> o2.sum - o1.sum);
// 用于去重
Set<String> visited = new HashSet<>();
int i = arr1.length - 1, j = arr2.length - 1, idx = 0;
maxHeap.offer(new Node(i, j, arr1[i] + arr2[j]));
visited.add(pos(i, j));
while (idx < k) {
Node cur = maxHeap.poll();
ans[idx++] = cur.sum;
i = cur.i;
j = cur.j;
if (i - 1 >= 0 && !visited.contains(pos(i - 1, j))) {
maxHeap.add(new Node(i - 1, j, arr1[i - 1] + arr2[j]));
visited.add(pos(i - 1, j));
}
if (j - 1 >= 0 && !visited.contains(pos(i, j - 1))) {
maxHeap.add(new Node(i, j - 1, arr1[i] + arr2[j - 1]));
visited.add(pos(i, j - 1));
}
}
return ans;
}
private static class Node {
private int i; // arr1中的位置
private int j; // arr2中的位置
private int sum; // arr[i] + arr[j]的值
public Node (int i, int j, int sum) {
this.i = i;
this.j = j;
this.sum = sum;
}
}
private static String pos(int i, int j) {
return String.format("%d_%d", i, j);
}
}
#优先队列的应用##topK问题##大根堆#线性表基础 文章被收录于专栏
链表、递归、栈
查看2道真题和解析