【牛客网】两个有序数组间相加和的Topk问题 [H](堆)
admin
2024-01-25 15:16:54
0

两个有序数组间相加和的Topk问题_牛客题霸_牛客网 (nowcoder.com)

一、题目

给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组。

按照降序输出。

要求:时间复杂度为O(k*log k)

示例 1:
输入:
5 4
1 2 3 4 5
3 5 7 9 11
输出:
16 15 14 14

二、代码

import java.util.Scanner;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StreamTokenizer in = new StreamTokenizer(br);PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));while (in.nextToken() != StreamTokenizer.TT_EOF) {int N = (int) in.nval;in.nextToken();int K = (int) in.nval;int[] arr1 = new int[N];int[] arr2 = new int[N];for (int i = 0; i < N; i++) {in.nextToken();arr1[i] = (int) in.nval;}for (int i = 0; i < N; i++) {in.nextToken();arr2[i] = (int) in.nval;}int[] topK = topKSum(arr1, arr2, K);for (int i = 0; i < K; i++) {out.print(topK[i] + " ");}out.println();out.flush();}}public static class Node {// 当前遍历到的arr1的下标,也就是矩阵的第一个下标public int i;// 当前遍历到的arr2的下标,也就是矩阵的第二个下标public int j;// 两个数组成的加和public int sum;public Node(int i, int j, int s) {this.i = i;this.j = j;this.sum = s;}}// 构造大根堆比较器,加和大的在堆顶public static class MaxHeapComp implements Comparator {@Overridepublic int compare(Node o1, Node o2) {return o2.sum - o1.sum;}}// 返回加和前k大的结果public static int[] topKSum(int[] arr1, int[] arr2, int k) {// 矩阵右下角就是加和的最大值,因为两个数组是有序的,最后一个数一定是最大的int i = arr1.length - 1;int j = arr2.length - 1;// 标记当前矩阵位置是否已经加入过大根堆// 这里使用矩阵的二位坐标转一维坐标来标记的HashSet set = new HashSet<>();// 创建大根堆PriorityQueue maxHead = new PriorityQueue<>(new MaxHeapComp());// 先将矩阵右下角的数加入大根堆maxHead.add(new Node(i, j, arr1[i] + arr2[j]));// 标记这个位置已经加入过大根堆了,二维坐标转一维坐标set.add(i * arr2.length + j);// 记录答案int[] ans = new int[k];int index = 0;// 如果k大于所有数的总数量,那么topK就设置为所有数的总数量int topK = Math.min(k, arr1.length * arr2.length);// 收集完topK就结束循环while (index != topK) {// 弹出堆顶,记录一个答案Node node = maxHead.poll();ans[index++] = node.sum;// 将弹出堆顶的上面和左边的位置加入到大根堆中,需要判断上面和下面是否还有数,并且这个数还不能加入过大根堆if (node.i > 0 && !set.contains((node.i - 1) * arr2.length + node.j)) {// 将上面的数加入大根堆maxHead.add(new Node(node.i - 1, node.j, arr1[node.i - 1] + arr2[node.j]));// 标记已经加入过堆了set.add((node.i - 1) * arr2.length + node.j);}if (node.j > 0 && !set.contains(node.i * arr2.length + (node.j - 1))) {// 将左面的数加入大根堆maxHead.add(new Node(node.i, node.j - 1, arr1[node.i] + arr2[node.j - 1]));// 标记已经加入过堆了set.add(node.i * arr2.length + (node.j - 1));}}// 返回答案return ans;}}

三、解题思路 

大根堆,想象出一个矩阵,但是代码并不会真的创建一个矩阵,还是在两个数组上进行遍历。arr1做行对应,arr2做列对应。

整个题就要利用两个数组的有序性。先去右下角的最大值,将其加入到大根堆中。此时大根堆中只有一个数,堆顶的就是目前找到的最大的数。

将堆顶数据弹出,记录下一个答案。

然后将该堆顶在矩阵中地所在位置的上面和左边的两组加和加入到大根堆中。这两个数中一定有仅次于刚才从堆中弹出那个数的,所以将他俩加入大根堆,此时的堆顶就是我们要的另一个答案。

整个过程就是在利用原数组的单调性,每次都一点点的减少横纵下标,而且会挑着比较大的那个位置将其上面和左边的加入到堆中,这样就能保证不会遗漏更大的数了,每次都是从最大的那个加和组合基础上来减少参与加和的两个数的大小

注意:防止同一个位置进入堆。要保证进大根堆不要重复进。是有可能出现这种情况的,所以要记录上哪些数已经进入过大根堆了。

相关内容

热门资讯

原创 还... 头条号墨山看客 首发呈现 大好河山,邀您共看 Hello,大家好呀!欢迎来到老墨聊时事, 6月18日...
商道创投网・会员动态|Mani... 《商道创投网》2026 年 06 月 21 日从官方获悉:Manifold AI 流形空间近日完成数...
原创 歌... 文|嘴嘴 编辑|嘴嘴 很多人第一次认识李琼,都是通过那首传遍大江南北的《山路十八弯》。旋律一响起,...
明天,深交所史上最大规模IPO... 根据目前安排,下周将有2只新股可申购:一只为避雷器、绝缘子“小巨人”,另一只为国内领先的新能源发电运...
一财社论:织牢降落伞打好AI淘... AI发展又迎来一个新的历史节点。 当前市场正在走出单纯基于“模型参数”的攻坚战,进入基于真实ROI(...
原创 游... 美国财政部刚公布了最新数据,咱们中国4月份又减持了12亿美元美债,持仓直接掉到了 6511亿美元。什...
明日申购!深交所史上最大规模I... 【大河财立方消息】华润新能源控股有限公司(简称:华润新能源)6月18日发布的公告显示,华润新能源A股...
高盛最新预测:大幅下调黄金价格 当地时间6月19日,国际金价再次收跌,截至发稿,COMEX黄金下跌1.72%,报4172.9美元/盎...
SpaceX行情降温两连跌 本... 来源:环球市场播报 受上周创纪录IPO后本轮股价上涨行情降温影响,SpaceX股票周四美股收盘下跌3...
台青看好粤港澳大湾区发展 刘玥晴 郑欣怡 “同心筑梦·青聚香江”海峡两岸暨港澳青年融合发展主题交流活动近日在香港举办。与会台湾...
小腿溃疡最佳治疗方案指南 小腿溃疡是临床常见的迁延难愈性创面,首先需要明确病因分型才能针对性治疗,不要盲目自行涂药或使用偏方,...
603986,存储芯片大牛股,... 【导读】下周A股将有49家公司有限售股份解禁 中国基金报记者 夏天 Wind数据显示,下周(6月22...
山东万福河被指遭污染近10公里... 一名环保博主6月21日上午发布现场调查视频称,山东济宁市金乡县万福河遭严重污染,其中部分河段河水黑如...
国产电子陶瓷商闯关港股!潮州三... 图源:图虫创意 来源|时代商业研究院 作者|实习生陈嘉婕、郑琳 编辑|郑琳 2026年6月8日,潮州...
*ST集友:控股股东、实际控制... *ST集友:控股股东、实际控制人拟协议转让部分公司股份 每经AI快讯,*ST集友(SH603429,...
端午假期最后一天 铁路运输迎来... 今天是端午假期最后一天,铁路运输迎来返程客流高峰。记者从国铁集团了解到,全国铁路预计发送旅客1794...
原创 美... 越来越多美国人不再相信美国经济为他们服务。 收入下滑、贫富分化是全球问题,但在美国,这两个问题又...
腰椎不适辨证针灸调理,从根源缓... 不少人长期久坐、弯腰劳作、受凉后都会出现腰椎酸胀、僵硬,严重时弯腰受限、牵扯腿疼麻木,现代多诊断腰肌...
莱伯泰科:公司发展战略立足于内... 证券日报网6月18日讯 ,莱伯泰科在接受调研者提问时表示,公司的发展战略立足于内生增长与外延扩张的双...