iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java怎么用堆解决Top-k问题
  • 412
分享到

Java怎么用堆解决Top-k问题

2023-06-30 02:06:42 412人浏览 泡泡鱼
摘要

本篇内容介绍了“Java怎么用堆解决Top-k问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、什么是堆?堆结构堆其实就是一种二叉树,但

本篇内容介绍了“Java怎么用堆解决Top-k问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1、什么是堆?

堆结构

堆其实就是一种二叉树,但是普通的二叉树是以链式结构进行储存数据的,而堆是以数组进行顺序存储数据的。那么什么样的二叉树才适合用顺序存储的方式呢?

我们假设一颗普通的二叉树可以用数组存储,那么就可以得到如下结构:

Java怎么用堆解决Top-k问题

我们可以看到,当二叉树中间有空值时,数组的存储空间会被浪费,那么什么情况下空间才不会被浪费呢? 那就是完全二叉树。

Java怎么用堆解决Top-k问题

从以上结构中,我们不能用链式结构的指针来访问孩子节点或者父亲节点,只能通过对应下标来访问,其实也比较简单。

例如下图:

已知 2 节点的下标是1,那么

他的左孩子下标是:2 * 2 + 1 = 3

他的右孩子下标是:2 * 2 + 2 = 4

相反,已知 1 节点的下标是3,3 节点的下标是4,那么

1 节点的父亲节点下标是:(3 - 1) / 2 = 1

3 节点的父亲节点下标是:(4 - 1) / 2 = 1

Java怎么用堆解决Top-k问题

大根堆 VS 小根堆

大根堆(最大堆)

大根堆保证,每颗二叉树的根节点都 大于 左右孩子节点

从最后一棵子树的根节点开始调整,来到每颗子树的根节点,使得每棵子树都向下调整为大根堆,最后再向下做最后调整,保证二叉树整体是大根堆(这个调整主要是为了后面的堆排序)。

Java怎么用堆解决Top-k问题

具体调整过程如下:

Java怎么用堆解决Top-k问题

Java怎么用堆解决Top-k问题

怎么用代码实现呢?

我们首先从最后一棵子树调整,那么就要拿到最后一颗子树的根节点 parent ,我们知道数组最后一个节点下标是 len - 1,而这个节点是最后一棵子树的左孩子或者右孩子,根据孩子下标就可以拿到根节点下标( parent ) ,parent-- 就可以让每颗子树都进行调整,直到来到根节点,再向下调整最后一次,便可以得到大根堆。

Java怎么用堆解决Top-k问题

// 将数组变成大根堆结构public void createHeap(int[] arr){    for (int i = 0; i < arr.length; i++) {        elem[i] = arr[i];// 放入elem[],假设不需要扩容        usedSize++;    }    // 得到根节点parent, parent--依次来到每颗子树的根节点,    for (int parent = (usedSize-1-1)/2; parent >= 0; parent--) {        // 依次向下搜索,使得每颗子树都变成大根堆        shiftDown(parent,usedSize);    }}// 向下搜索变成大根堆public void shiftDown(int parent,int len){    int child = parent*2+1;// 拿到左孩子    while (child < len){        // 如果有右孩子,比较左右孩子大小,得到较大的值和父节点比较         if (child+1 < len && (elem[child] < elem[child+1])){            child++;        }        // 比较较大的孩子和父节点,看是否要交换        int max = elem[parent] >= elem[child] ? parent : child;        if (max == parent) break;// 如果不需要调整了,说明当前子树已经是大根堆了,直接 break        swap(elem,parent,child);        parent = child;// 继续向下检测,看是否要调整        child = parent*2+1;    }}public void swap(int[] arr,int i,int j){  int temp = arr[i];    arr[i] = arr[j];    arr[j] = temp;}
小根堆(最小堆)

小根堆保证,每颗二叉树的根节点都 小于 左右孩子节点

调整过程同上。

Java怎么用堆解决Top-k问题

优先级队列(PriorityQueue)

在java中,提供了堆这种数据结构(PriorityQueue),也叫优先级队列,当我们创建一个这样的对象时,就得到了一个没有添加数据的 小根堆 ,我们可以向里面添加或者删除元素,每向里面删除或者添加一个元素,系统会整体进行一次调整,重新又调整为小根堆。

// 默认得到一个小根堆PriorityQueue<Integer> smallHeap = new PriorityQueue<>();smallHeap.offer(23);smallHeap.offer(2);smallHeap.offer(11);System.out.println(smallHeap.poll());// 弹出2,剩余最小的元素就是11,会被调整到堆顶,下一次弹出System.out.println(smallHeap.poll());// 弹出11 // 如果需要得到大根堆,在里面传一个比较器 PriorityQueue<Integer> BigHeap = new PriorityQueue<>(new Comparator<Integer>() {     @Override     public int compare(Integer o1, Integer o2) {         return o2 - o1;     } });

2、top-k问题解决思路

例:有一堆元素,让你找出前三个最小的元素。

思路一: 将数组从小到大排序,拿到数组前3个元素。但是可以发现这样时间复杂度太高,不可取。

思路二: 将元素全部放入一个堆结构中,然后弹出三个元素,每次弹出的元素都是当前堆最小的,那么弹出的三个元素就是前最小的三个元素。

这种思路可以做,但是假设我有1000000个元素,只弹出前三个最小的元素,那么就要用到大小为1000000的堆。这么做空间复杂度太高,不建议用这种方法。

思路三:

我们需要得到三个最小的元素,那么就建一个大小为3的堆,假设目前的堆结构中刚好放满了3个元素,那么这三个元素就是当前最小的三个元素。假设第四个元素是我们想要的元素之一,那么前三个至少有一个元素不是我们想要的,就需要弹出,那么弹出谁呢?

我们要得到的是前三个最小的元素,所以当前堆结构中最大的元素一定不是我们想要的,所以这里我们建一个大根堆。弹出该元素,然后放入第四个元素,直到遍历完整个数组。

Java怎么用堆解决Top-k问题

Java怎么用堆解决Top-k问题

Java怎么用堆解决Top-k问题

这样我们就得到了只含有前三个最小元素的堆,并且可以看到堆的大小一直都是3,而不是有多少数据就建多大的堆,然后再依次弹出元素就行了。

// 找前 k个最小的元素public static int[] topK(int[] arr,int k){     // 创建一个大小为 k的大根堆     PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k,new Comparator<Integer>() {         @Override         public int compare(Integer o1, Integer o2) {             return o2 - o1;         }     });     for (int i = 0; i < arr.length; i++) {         if (i < k){             // 放入前 k 个元素             maxHeap.offer(arr[i]);         }else{             // 从第 k+1个元素开始进行判断是否要入堆             if (maxHeap.peek() > arr[i]){                 maxHeap.poll();                 maxHeap.offer(arr[i]);             }         }     }     int[] ret = new int[k];     for (int i = 0; i < k; i++) {         ret[i] = maxHeap.poll();     }     return ret; }

“Java怎么用堆解决Top-k问题”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: Java怎么用堆解决Top-k问题

本文链接: https://www.lsjlt.com/news/327104.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java怎么用堆解决Top-k问题
    本篇内容介绍了“Java怎么用堆解决Top-k问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、什么是堆?堆结构堆其实就是一种二叉树,但...
    99+
    2023-06-30
  • Java 详细讲解用堆解决Top-k问题
    目录1、什么是堆?堆结构大根堆 VS 小根堆大根堆(最大堆)小根堆(最小堆)优先级队列(PriorityQueue)2、top-k问题解决思路总结:要解决 top-k 问题,我们应该...
    99+
    2024-04-02
  • Java怎么解决Top-K的问题
    这篇文章主要介绍“Java怎么解决Top-K的问题”,在日常操作中,相信很多人在Java怎么解决Top-K的问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java怎么解决Top-K的问题”的疑惑有所帮助!...
    99+
    2023-06-30
  • Java深入分析与解决Top-K问题
    目录题目解题方案方法一方法二方法三题目 求最小的K个数 设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。 解题方案 方法一 排序(冒泡/选择) 思路 1,冒泡排序...
    99+
    2024-04-02
  • 【数据结构】堆的实现,堆排序以及TOP-K问题
    目录 1.堆的概念及结构 2.堆的实现 2.1初始化堆 2.2销毁堆 2.3取堆顶元素 2.4返回堆的大小 2.5判断是否为空 2.6打印堆 2.7插入元素 2.8堆的向上调整 2.9弹出元素 2.10堆的向下调整 3. 建堆时间复杂度...
    99+
    2023-09-06
    数据结构 算法
  • java堆内存溢出问题怎么解决
    Java堆内存溢出问题的解决方法有以下几种: 增加堆内存大小:可以通过修改JVM的启动参数,增加堆内存的大小,例如增加-Xmx参...
    99+
    2023-10-27
    java
  • rabbitmq堆积问题怎么解决
    RabbitMQ堆积问题可以通过以下几种方式来解决: 增加消费者:可以通过增加消费者来提高消费速度,减少消息堆积。可以通过启动多个...
    99+
    2023-10-26
    rabbitmq
  • margin-top的传递问题怎么解决
    这篇文章主要介绍了margin-top的传递问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇margin-top的传递问题怎么解决文章都会有所收获,下面我们一起来看看...
    99+
    2024-04-02
  • C语言怎么用堆解决Topk问题
    这篇文章给大家分享的是有关C语言怎么用堆解决Topk问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言将详细讲解如何利用小根堆的方法解决TopK问题,这么多数据要处理,该算法时间复度居然只需TopK问题Top...
    99+
    2023-06-21
  • 堆排序怎么解决TopK问题
    本篇内容主要讲解“堆排序怎么解决TopK问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“堆排序怎么解决TopK问题”吧!在未排序的数组中找到第 k 个最大的元...
    99+
    2024-04-02
  • windows堆栈平衡问题怎么解决
    解决Windows堆栈平衡问题的方法取决于具体的情况和根因。以下是一些可能的解决方法:1. 检查代码中的递归调用:如果代码中存在递归...
    99+
    2023-10-18
    windows
  • log4net堆栈溢出问题怎么解决
    Log4net的堆栈溢出问题可能是由于日志消息的递归输出或无限循环造成的。以下是一些可能的解决方案:1. 确保日志消息中没有无限循环...
    99+
    2023-09-16
    log4net
  • kafka怎么解决数据堆积问题
    Kafka是一种分布式的流处理平台,可以高效地处理大量的数据流。解决数据堆积问题,可以通过以下几种方式:1. 增加消费者数量:可以通...
    99+
    2023-10-21
    kafka
  • 如何解决margin-top塌陷的问题
    这篇文章给大家分享的是有关如何解决margin-top塌陷的问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是margin-top塌陷margin-top塌陷是在CSS的盒...
    99+
    2024-04-02
  • daisyUI解决TailwindCSS堆砌class问题详解
    目录 写在前面daisyUI概述 丰富的资源 对比TailwindCSS 顽强的适用性 快速上手 自定义主题 封装一个button组件 写在最后 写在前面 关于TailwindCSS...
    99+
    2024-04-02
  • C语言 如何用堆解决Topk问题
    目录前言TopK问题解题方法代码实现与讲解运行结果函数解读PrintTopK 解读TestTopK 解读前言 本篇将详细讲解如何利用小根堆的方法解决TopK问题,这么多数据要处理, ...
    99+
    2024-04-02
  • 怎么用java解决背包问题
    背包问题是一个经典的组合优化问题,可以使用动态规划来解决。以下是使用Java语言解决背包问题的一个示例: public class ...
    99+
    2023-10-24
    java
  • Java循环引用问题怎么解决
    在Java中,循环引用问题通常是指两个或多个对象相互引用,导致无法被垃圾回收器回收,从而造成内存泄漏的情况。要解决循环引用问题,可以...
    99+
    2023-10-07
    Java
  • 使用Java怎么解决跨域问题
    今天就跟大家聊聊有关使用Java怎么解决跨域问题,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。什么是跨域(CORS)跨域(CORS)是指不同域名之间相互访问。跨域,指的是浏览器不能执...
    99+
    2023-06-06
  • Java死锁问题怎么解决
    今天小编给大家分享一下Java死锁问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。前言:死锁(Dead Lock)...
    99+
    2023-06-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作