两个有序数组间相加和的TopK问题 - 优先队列

优先队列,二叉堆以及topK问题 1.优先队列是按照优先级排序的队列,优先级大(默认)的先出。 2.二叉堆是一颗完全二叉树。 树的任意节点值大于等于其子节点:最大堆。 树的任意节点值小于等于其子节点:最小堆 完全二叉树通常使用数组存储,节点之间对应的下标关系是:某一结点下标i,则父节点下标[i / 2], 左节点2 * i ,右节点2 * i + 1. 可以认为优先队列就是实现大顶堆或小顶堆的数组。 这是一个大顶堆,所以说优先队... 阅读详情

题目描述

链接:https://www.nowcoder.com/questionTerminal/7201cacf73e7495aa5f88b223bbbf6d1

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

要求:
1. 按照降序输出
2. 时间复杂度为O(klogk)

题目分析

这道题的正确解法为使用优先队列.

我们已知,两个数组是有序的, 然而要求递减的两个数组成的最大和, 那么必然有一定的规律性.

  • 右下角的数必定是最大的
  • 我们每次需要判断的是: 右下角的上方和左方(固定最大行和固定最大列, 哪个更大)
  • 利用优先队列做BFS搜索即可, 如果找到了K个数, 直接return. 复杂度为KlogK.

代码 (注意边界)

import java.util.*;
public class Code04_TopKSumCrossTwoArrays {

    public static class Node {
        int x;
        int y;
        int sum;
        public Node(int x, int y, int sum) {
            this.x = x;
            this.y = y;
            this.sum = sum;
        }
    }
    public static class MaxHeapComp implements Comparator<Node> {
        @Override
        public int compare(Node o1, Node o2) {
            return o2.sum - o1.sum;
        }
    }

    public static int[] topKSum(int[] arr1, int[] arr2, int topK) {
        if (arr1 == null || arr2 == null || topK < 1) return null;
        topK = Math.min(topK, arr1.length * arr2.length);
        int[] res = new int[topK];
        int resIndex = 0;
        // 建立大根堆
        PriorityQueue<Node> maxHeap = new PriorityQueue<>(new MaxHeapComp());
        boolean[][] visit = new boolean[arr1.length][arr2.length];
        int i1 = arr1.length - 1;
        int i2 = arr2.length - 1;
        // 初始化队列
        maxHeap.add(new Node(i1, i2, arr1[i1] + arr2[i2]));
        visit[i1][i2] = true;
        while (resIndex != topK) {
            Node curNode = maxHeap.poll();
            if (curNode == null) break;
            res[resIndex] = curNode.sum;
            i1 = curNode.x;
            i2 = curNode.y;
            if (i1 - 1 >= 0 && !visit[i1-1][i2]) {
                visit[i1-1][i2] = true;
                maxHeap.add(new Node(i1 - 1, i2, arr1[i1-1] + arr2[i2]));
            }
            if (i2 - 1 >= 0 && !visit[i1][i2-1]) {
                visit[i1][i2-1] = true;
                maxHeap.add(new Node(i1, i2-1, arr1[i1] + arr2[i2-1]));
            }
            resIndex++;
        }
        return res;
    }
    public static void main(String[] args) {
        int n, k;
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        k = sc.nextInt();
        int[] arr1 = new int[n];
        int[] arr2 = new int[n];
        for (int i = 0; i < n; i++) {
            arr1[i] = sc.nextInt();
        }
        for (int i = 0; i < n; i++) {
            arr2[i] = sc.nextInt();
        }
        int[] res = topKSum(arr1, arr2, k);
        for (int i = 0; i < res.length; i++) {
            if (i == 0) System.out.print(res[i]);
            else System.out.print(" " + res[i]);
        }
        System.out.println();
    }
}
[Dify] 如何在Dify中解析上传的TXT文件内容 在Dify平台上构建智能应用时,解析用户上传的.txt文件是关键步骤。 阅读详情

相关推荐

【解决方案】使用transformer指定显卡后,模型依然加载到默认第1张显卡上

按理说指定了环境变量为后面几张显卡,模型会自动加载到我们指定的显卡上。可是查看gpu使用情况,发现还是加载在了第一张显卡上,这是为啥呢?

m0_56745306的博客 2441

其他题目---两个有序数组间相加和的TopK问题

【题目】  给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组。要求时间复杂度O(klogk)。【基本思路】  使用大根堆结构。假设arr1的长度是M,arr2的长度是N。因为是排序数组,arr1中最后一个数加上arr2中最后一个数一定就是最大的相加和。将这个数压入大根堆中。然后从大根堆中弹出一个堆顶,此时这个堆顶一

冰殇的博客 3136

从BAM到bigWig:用UCSC工具链完成测序数据可视化的完整流程

本文详细介绍了从BAM文件到bigWig格式的基因组数据可视化完整流程,涵盖UCSC工具链配置、文件格式转换、参数优化及常见问题解决方案。通过实战指南帮助研究人员高效完成测序数据可视化,特别适合ChIP-seq和RNA-seq数据分析。

weixin_29309213的博客 707

牛客网:两个有序数组间相加和的Topk问题

分析数据量,一定是O(N)级别的算法。

OceanStar的博客 456

从IR Drop到EM分析:数字IC电源规划中那些没人明说的细节(以MTCMOS配置为例)

本文深入探讨数字IC后端设计中电源规划的关键细节,特别关注MTCMOS配置、电源网络电阻最小化和level shifter供电等实战技巧。通过分析IR Drop和EM问题,提供优化floorplan和powerplan的具体策略,帮助工程师避免常见陷阱,提升芯片设计的稳定性和可靠性。

q9w8e7r6t5的博客 511

LS-Dyna模态分析实战:从模型构建到结果解读的全流程指南

本文提供了一份详尽的LS-Dyna模态分析实战指南。文章系统讲解了如何利用LS-Dyna内置的隐式求解器进行特征值求解,从模型构建、几何清理、材料与连接设置,到核心的边界条件与隐式求解控制(如*CONTROL_IMPLICIT_EIGENVALUE),最后完成计算并解读频率与振型结果。旨在帮助工程师在熟悉的环境中高效完成结构振动特性分析,为后续动态响应分析奠定基础。

info6的博客 263

两个有序数组间相加和的Topk问题

题目 两个有序数组间相加和的Topk问题 考查点:堆 + 哈希表 分析 数据是十万,所以考虑O(NlogN)O(NlogN)O(NlogN)以下的解法。因为是TopK问题,所以暗示用堆,每次从堆中取出最大值,所以需要大根堆。放入堆中的元素不能有重复,因此要使用哈希表判重。另外,最大值只能是两种情况。 a数组往前移动一格,a[i-1] + b[j] b数组往前移动一格,a[i] + b[j-1] 所以每次将这两种值扔进大根堆中,取出k个值即为答案。 代码 #include <bits/st

姚军 1036

【DRAM存储器五十一】LPDDR5介绍--DFE与Pre-Emphasis

简述LPDDR5的DFE和预加重应用设置

highman110的博客 706

【牛客网】两个有序数组间相加和的Topk问题 [H](堆)

两个有序数组间相加和的Topk问题:给定两个有序数组 arr1 和 arr2,再给定一个整数 k,返回来自 arr1 和 arr2 的两个数相加和最大的前 k 个,两个数必须分别来自两个数组, 按照降序输出。采用堆结构求解。

小七的博客 961

使用 MATLAB/Simulink + Simscape Electrical,构建一个含光伏并网系统与SVG的联合仿真模型,实现动态无功补偿与电压支撑

摘要:本文详细介绍了基于Simulink的SVG与光伏并网逆变器联合系统建模方法。通过构建包含光伏单元、SVG主电路和控制模块的仿真模型,实现动态无功补偿与电压稳定。重点阐述了ip-iq无功检测算法、双闭环控制和SVPWM调制等关键技术。仿真结果表明,该系统能快速响应无功需求,在10ms内将功率因数提升至0.98以上,有效抑制电压波动。文章为新能源并网系统中的电能质量治理提供了实用解决方案,并提出了进一步优化方向。

xiaoheshang_123的博客 322

开源Harness项目DeerFlow 2.0,让智能体几乎能完成任何复杂任务

从提示工程到上下文工程,再到如今的 Harness,这条演进路径的本质是从“教模型如何理解人类”迈向“为模型构建一个可执行、可信赖、可长期运转的数字世界”。 当越来越多像 DeerFlow 2.0 这样的 Super Agent Harness 走向普及,AI 将真正进化为能理解、会规划、可执行、敢交付、长期负责的成熟生产力形态。

技术引领业务创新 519

Leetcode 两个有序数组间相加的TopK

题目描述 给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组 按照降序输出 输入描述: 第一行三个整数N, K分别表示数组arr1, arr2的大小,以及需要询问的数 接下来一行N个整数,表示arr1内的元素 再接下来一行N个整数,表示arr2内的元素 输出描述: 输出K个整数表示答案 输入 5 4 1 2 3 4 5 3 5 7 9 11 输出 16 15 14 14 对于TopK问题,例如经典的海量数组中

一只老风铃 4095

GeoScene Pro教程(002):GeoScenePro基础操作

GeoScenePro基础操作介绍。

WwLK123的博客 2461

【C++】【手撕】【top K】两个有序数组间相加和的Topk问题;优先队列、最大堆。

题目描述 https://www.nowcoder.com/questionTerminal/7201cacf73e7495aa5f88b223bbbf6d1 文章目录题目描述一、思路二、难点:三、代码四、实现:五、更进一步考察的点: 一、思路 [要求] 时间复杂度为O(k \log k)O(klogk) 大概能猜出来要用最大堆来实现了。然后再加上用个bfs来扫描周围的最大值。 即: 将右下角唯一知道的最大值压入最大堆; 弹出最大堆中最大的值,这个值就可以加入最终结果中; 将这个最大值的左边节点和上

多丰富下自己呀 1469

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

牛客网-两个有序数组间相加和的Topk问题

一.题目描述 给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组 按照降序输出 两个有序数组间相加和的Topk问题__牛客网 二.代码 import java.util.*; public class Main { static class Node { public int index1; //arr1中的位置 public int index2; //arr2中的位

pubgNO1的博客 738

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

小根堆和大根堆——优先队列问题

堆序性:每个节点的值都大于等于(或小于等于)其子节点的值。大根堆:每个节点的值都大于等于其子节点的值,根节点是最大值。小根堆:每个节点的值都小于等于其子节点的值,根节点是最小值。完全二叉树:除了最后一层,其他层的节点都必须填满,且最后一层的节点都靠左排列。堆是一种高效的数据结构,在解决优先队列、TopK问题、堆排序等问题时具有显著优势。理解堆的性质和操作,并掌握其应用场景,对于提升算法能力和解决实际问题至关重要。希望本文能够帮助你更好地理解和应用堆结构!有一堆石头,每块石头的重量都是正整数。

tanactor的博客 3093

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

设计:优先队列、TOPK问题

文章目录TopK引入堆排序PriorityQueue源码简析写一个优先队列 TopK引入 又这么几种问题:求出当前数组最小值、求出当前数据流中第K大的数。 前者是一个固定的范围,而后者是一个变化的范围(当然了,你也可以看作若干个固定范围的快照)。解决以上问题的一个思路是排序,则难以避免需要扫描整个数组的值,而基于堆排序的时间复杂度是O(n*logK) 调整的时间复杂度取决于堆的高度,将K个元素组成一个堆(数组形式的完全二叉树),因此可以调整的时间复杂度就是logK,如果你对整个数组建堆那么调整的时间复杂度

qq_44793993的博客 395

快速选择与优先队列那个更适合实现TopK问题?

本文介绍了解决TopK问题的两种主要算法:快速选择算法和堆排序解法。快速选择算法基于快速排序的分治思想,通过分区操作平均时间复杂度达到O(n),适合处理能一次性加载到内存的数据。堆排序解法利用小顶堆/大顶堆特性,保持稳定的O(nlogK)时间复杂度,特别适合海量数据场景。文章详细分析了两种算法的实现原理、复杂度差异和适用场景,并提供了C++代码示例。对于超大规模数据(如10亿条记录),堆解法因其固定内存开销(O(K))成为首选方案。此外还简要提及了计数排序等特殊场景下的优化方法。

m0_62807361的博客 1605

遨游优先队列与topK

队列我们已经用的很熟了,那加上优先两个字是否还是和队列一样呢? 非也,非也 优先队列(PriorityQueue):看见这个名称是不是能猜到点什么… PriorityQueue类在Java1.5中引入。它作为 Java Collections Framework 的一部分。PriorityQueue是基于优先堆的一个无界队列,这个优先队列中的元素可以默认自然排序或者通过提供的Comparator(...

weixin_42373873的博客 233

【算法题刷完这遍该会了】最小 K 个数 - TopK 问题

这道题是经典的 TopK 问题,通过逐步优化,我们从最直观的排序解法,到使用优先队列的解法,最后使用快速选择实现最优解。排序:代码最直观,适合面试时快速实现先过一版优先队列:适合数据流场景,可以动态维护 k 个最小元素快速选择:平均时间复杂度最优,适合静态数组。

南风吹梦 2714

topk算法

问题 对于海量数据到处理经常会涉及到 topK 问题。在设计数据结构和算法的时候,主要需要考虑的应该是当前算法(包括数据结构)跟给定情境(比如数据量级、数据类型)的适配程度,和当前问题最核心的瓶颈(如降低时间复杂度,还是降低空间复杂度)是什么。 首先,我们来举几个常见的 topK 问题的例子: 给定 100 个 int 数字,在其中找出最大的 10 个; 给定 10 亿个 int 数字,在其中找出最大的 10 个(这 10 个数字可以无序); 给定 10 亿个 int 数字,在其中找出最大的 10 个(这

qq_40813329的博客 4659

堆排序和N个数组的topK问题

堆排序 本文主要通过实现一个小根堆排序对堆排序进行一个说明。 堆排序具体分为以下几个函数进行实现: heapify(int[] nums, int n, int len) heapInitial(int[] nums, int n) heapSort(int[] nums) heapify(int[] nums,int n, int len); 这个函数是堆排序的核心函数,其表示对n为下标的节...

EnonLay的博客 618

优先队列与TopK

一、简介   前文介绍了《最大堆》的实现,本章节在最大堆的基础上实现一个简单的优先队列。优先队列的实现本身没什么难度,所以本文我们从优先队列的场景出发介绍topK问题。   后面会持续更新数据结构相关的博文。   数据结构专栏:https://www.cnblogs.com/hello-shf/category/1519192.html   git传送门:https://g...

weixin_30508309的博客 399

堆排序进阶:优先队列自定义比较器与 TopK 问题

堆排序是一种高效的排序算法,基于二叉堆数据结构实现,时间复杂度为 $O(n \log n)$。优先队列是堆排序的典型应用,它允许我们高效地插入和删除元素(如获取最大值或最小值)。在进阶应用中,我们可以通过自定义比较器来改变优先队列的排序行为,从而解决 TopK 问题(即从一个序列中找出最大的 K 个或最小的 K 个元素)。下面我将逐步解释这些概念,并提供代码实现。自定义比较器允许我们定义元素的优先级顺序,例如,基于对象的某个属性排序(如按年龄、分数等)。方法:使用元组,其中priority。

2501_93878031的博客 1000

经典面试题目——TopK问题

你还记得TopK问题吗?这可是面试中常考的呀!

日常学习记录、分享,愿我们都遇见更好的自己,与诸君共勉 2514

算法:TopK问题,使用堆排序和优先队列PriorityQueue

TopK 从一亿个数据中找到前100个最大值 将无需序列构建成一个堆,根据升序降序需求选择大小为K的大顶堆或小顶堆; 将堆顶元素与数组中的元素比较,比堆顶大的元素,先弹出堆顶,然后元素入堆 时间复杂度O(NlogK) import java.util.Arrays; public class TopKHeapSort { public static void main(String[] args) { int[] arrs = new int[10000*10000];

fangfeng1021的博客 347
上一篇: 跳跃游戏 - 递推
下一篇: 交错字符串 - 动态规划
程序员布隆
博客等级 码龄9年 15粉丝 84原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值