【牛客网】两个有序数组间相加和的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做列对应。

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

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

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

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

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

相关内容

热门资讯

新生代妈妈偏好的孕育平台:专业... 概述 母婴垂类平台在用户定位、业务模式与内容生态方面存在差异。例如,妈妈网侧重于为新手妈妈提供全周期...
金普新区去年新登记经营主体超3... 想创业投资,哪里活力旺、服务优?金普新区最新“成绩单”给出了生动答案——去年全年新增经营主体超过3....
海南封关满月看变化:离岛免税消... 中新网海口1月17日电 (记者 王子谦)海南自贸港全岛封关满月将至。记者17日从cdf海口国际免税城...
13年最低:金银比跌至50!黄... 王爷说财经讯:暴跌预警?金银比创13年最低! 注意了!金融市场又炸雷了! 就在今天,2026年1月1...
不低于30%!商业用房购房贷款... 1月17日,中国人民银行、国家金融监督管理总局发布关于调整商业用房购房贷款最低首付款比例政策的通知,...
商道创投网·会员动态|星融元·... 《商道创投网》2026年1月17日从官方获悉:星融元数据技术有限公司(Asterfusion)近日完...
原创 美... 近日,海关发布了中国2025年的进出口情况。 而关注芯片产业的人发现,2025年,中国出口芯片数量3...
爆款刚诞生,德邦基金为何急下“... 来源:市场资讯 作者 |郑理 来源 | 独角金融 2026年的公募市场,被一只名不见经传的AI应用...
欧陆之星钻石被出具警示函,涉未... 蓝鲸新闻1月17日讯,近日,江苏证监局发布行政监管措施决定书,剑指欧陆之星钻石(上海)有限公司。 决...
木林森涨1.76%,成交额4.... 来源:新浪证券-红岸工作室 1月16日,木林森涨1.76%,成交额4.35亿元,换手率4.20%,总...
金一文化跌3.63%,成交额2... 来源:新浪证券-红岸工作室 1月16日,金一文化跌3.63%,成交额2.04亿元,换手率2.38%,...
险资系私募基金总数量增至11只 险资长期股票投资试点正加速落地。中国证券投资基金业协会信息显示,国丰兴华鸿鹄志远三期私募证券投资基金...
邹加怡出任亚洲基础设施投资银行... 央广网北京1月16日消息(记者 宓迪)据“亚洲基础设施投资银行”微信公众号,今日,邹加怡正式就任亚洲...
汉德精密:向外走、向深拓 抢占... 全球产业分工重构之际,中国装备制造企业出海已从“规模扩张”迈入“提质增效”新阶段,而产业链协同共生成...
中央财政加力支持 民间专项担保... 围绕支持民间投资,日前召开的2026年首场国务院常务会议提出设立“民间投资专项担保计划”,这意味着我...
我们该如何应对“难治性双相情感... “前一秒还情绪高涨、斗志昂扬,下一秒就陷入低谷、悲观绝望”——这不是简单的“心情不好”,而是双相情感...
和讯投顾刘文博:指数高开低走,... 1月16日,和讯投顾刘文博表示,今早A股高开回应,但因整体调整尚不充分,市场合力未能持续,指数最终回...
80多家央企“一把手”2024... 本报(chinatimes.net.cn)记者刘昱汝 徐芸茜 北京报道 日前,国资委官网通过集中发布...
2026义乌电商博览会·跨境服... 在全球数字经济浪潮下,中国电商服务生态凭借完善的产业链协同与持续创新的技术能力,正成为推动跨境贸易增...
罗永浩需要为西贝预制菜风波担责... 16日下午,贾国龙更新微博称:“今晚(16日)10点将就罗永浩对西贝的重大污蔑诽谤一一全面回应”,并...