【LeetCode】八、堆的使用:第K个最大元素 + 前K和高频单词

news2024/9/17 8:30:03

文章目录

  • 1、Java中的堆结构
  • 2、leetcode215:数组中的第K个最大元素
  • 3、leetcode692:前K个高频单词

1、Java中的堆结构

  • PriorityQueue类
  • 取堆顶元素
  • 删除堆顶元素
  • 堆的元素个数
  • 遍历堆

在这里插入图片描述

2、leetcode215:数组中的第K个最大元素

在这里插入图片描述
这题应该快排来解,这里用堆仅做练习。用堆实现的思路:将数组存入最大堆,k=1,找第一大的元素,则取堆顶元素,k=2,找第二大的元素,则删掉堆顶元素,取最新的堆顶元素,k=3,则删掉两次堆顶元素后,取新的堆顶元素

public class P215 {

    public static int getKMax(int[] array, int k) {
        if (array == null || array.length == 0 || k < 1){
            return Integer.MIN_VALUE;
        }
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
        for (int i : array) {
            maxHeap.add(i);
        }
        while (k > 1) {
            // 删掉前面第k-1大的所有元素
            maxHeap.poll();
            k--;
        }
        // 取出删掉后新的堆顶元素,即第K大的元素
        return maxHeap.peek();
    }
}

测试:

public class P215 {
    public static void main(String[] args) {
        int[] array = {3, 2, 3, 1, 2, 4, 5, 5, 6};
        System.out.println(getKMax(array, 4));
    }
}

在这里插入图片描述

3、leetcode692:前K个高频单词

在这里插入图片描述

本质是个统计次数的问题,自然想到哈希表结构,可用HashMap,统计完后,前k个、第K个,则可考虑最大堆。不过,题中要求次数相等时,按照字母排序,因此,要自定义比较器的实现:先比次数,次数相等再按字母排序

在这里插入图片描述

如果要用最小堆实现:应该将值最小的元素往堆顶放、同等次数的把字母靠后的往堆顶放

在这里插入图片描述

然后,限制最小堆里元素的个数为k个,当超出k时,剔除堆顶元素,因为堆顶元素最小,我要的是前K大的。遍历map完成后,从堆中循环取出堆顶数据,此时得到的顺序是从小到大的,再反转下,即可return

在这里插入图片描述

这里用最小堆和最小堆分别来解决:

public class P692 {

    /**
     * 统计每个单词出现的数量
     */
    public static HashMap<String, Integer> stats(String[] array) {
        if (array == null || array.length == 0) {
            return null;
        }
        HashMap<String, Integer> statsMap = new HashMap<>();
        for (String str : array) {
            // 判断下是否包含这个key,不要直接map.get(str) + 1
            // 没这个key时,get返回null,null + 1会空指针
            if (!statsMap.containsKey(str)) {
                statsMap.put(str, 1);
            } else {
                statsMap.put(str, statsMap.get(str) + 1);
            }
        }
        return statsMap;
    }

    /**
     * 用最小堆解题
     */
    public static List<String> calcKMaxByMinHeap(HashMap<String, Integer> map, Integer k) {
        PriorityQueue<StrInfo> minHeap = new PriorityQueue<>(new Comparator<StrInfo>() {
            @Override
            public int compare(StrInfo o1, StrInfo o2) {
                if (!o1.count.equals(o2.count)) {
                    return o1.count - o2.count;
                } else {
                    return o2.str.compareTo(o1.str);
                }
            }
        });
        map.forEach((str, count) -> {
            // 将每一条统计数据入堆,入堆时会按照上面的比较规则做成最小堆
            minHeap.add(new StrInfo(str, count));
            // 入堆后如果元素数量超过了k,扔掉堆顶元素
            if (minHeap.size() > k) {
                minHeap.poll();
            }
        });

        // 将堆中的k个单词放入结果集
        List<String> result = new ArrayList<>();
        while (!minHeap.isEmpty()) {
            result.add(minHeap.poll().str);
        }
        // 结果倒转,按题目要求的顺序return
        Collections.reverse(result);
        return result;
    }

    /**
     * 用最大堆解题
     */
    public static List<String> calcKMaxByMaxHeap(HashMap<String, Integer> map, Integer k) {
        PriorityQueue<StrInfo> maxHeap = new PriorityQueue<>(new Comparator<StrInfo>() {
            @Override
            public int compare(StrInfo o1, StrInfo o2) {
                if (!o1.count.equals(o2.count)) {
                    return o2.count - o1.count;
                } else {
                    return o1.str.compareTo(o2.str);
                }
            }
        });
        // 将每一条统计数据入堆,入堆时会按照上面的比较规则做成最大堆
        map.forEach((str, count) -> {
            maxHeap.add(new StrInfo(str, count));
        });
        // 取前k个堆顶元素即为前K个高频单词
        List<String> result = new ArrayList<>();
        while (k > 0) {
            result.add(maxHeap.poll().str);
            k--;
        }
        return result;

    }
}


class StrInfo {
    String str;
    Integer count;

    public StrInfo(String str, Integer count) {
        this.str = str;
        this.count = count;
    }
}

测试:

public class P692 {
    public static void main(String[] args) {
        String[] array = {"i", "love", "leetcode", "i", "love", "coding"};
        System.out.println(calcKMaxByMinHeap(stats(array), 2));
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1870589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年6月27日 (周四) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键&#xff0c;实现一键唤起、一键隐藏的 Windows 工具&#xff0c;并且支持窗口动态绑定快捷键&#xff08;无需设置自动实现&#xff09;。 喜马拉雅下载工具: 字面意思 Steam国产“类8番”游戏《永恒逃脱&#xff1a;暗影城堡》…

Elasticsearch8.x聚合查询全面指南:从理论到实战

聚合查询的概念 聚合查询&#xff08;Aggregation Queries&#xff09;是Elasticsearch中用于数据汇总和分析的查询类型。它不同于普通的查询&#xff0c;而是用于执行各种聚合操作&#xff0c;如计数、求和、平均值、最小值、最大值、分组等。 聚合查询的分类 分桶聚合&…

web端使用HTML5开发《贪吃蛇》小游戏教程【附源码】

自制游戏列表 1植物大战僵尸自制HTML5游戏《植物大战僵尸》2开心消消乐自制HTML5游戏《开心消消乐》3贪吃蛇自制HTML5游戏《贪吃蛇》4捕鱼达人自制HTML5游戏《捕鱼达人》 一、游戏简介 贪吃蛇是一款经典的电子游戏&#xff0c;最早在1976年由Gremlin公司推出&#xff0c;…

牛筋面,一口难忘的劲道滋味

在众多的平凉美食中&#xff0c;牛筋面以其独特的口感和丰富的口味&#xff0c;赢得了无数食客的喜爱。牛筋面&#xff0c;这一名字就给人一种坚韧、有嚼劲的印象。它并非由牛筋制成&#xff0c;而是因其面条的口感如牛筋般劲道而得名。牛筋面的制作过程颇具巧思。选用优质的面…

Unity免费领高级可视化编程自定义节点工具AI行为UI流程对话树状态机逻辑等FlowReactor价值50刀high level20240627

刚发现一款类似虚幻蓝图的可视化编程工具&#xff0c;原价50刀&#xff0c;现在免费领取了。赶紧去领取入库&#xff0c;防止作者涨价。 高级可视化编程自定义节点工具&#xff1a;https://prf.hn/l/BJbdvnD 作者其他资产&#xff1a;https://prf.hn/l/YLAYznV Unity免费领高级…

电脑提示msvcr120.dll丢失怎样修复

文件功能与重要性&#xff1a;msvcr120.dll 文件的功能和重要性体现在多个方面&#xff0c;以下是对其核心功能的详细分析&#xff1a; 运行时支持 msvcr120.dll 提供了运行时环境&#xff0c;使得使用 Microsoft Visual C 2013 编译的程序能够调用必要的运行时函数。这些函数…

MySQL高级-索引-使用规则-覆盖索引回表查询

文章目录 1、覆盖索引1.1、查看索引1.2、删除单列索引 idx_user_pro1.3、查询 profession软件工程 and age31 and status01.4、执行计划 profession软件工程 and age31 and status01.5、执行计划 select id,profession,age,status1.6、执行计划 select id,profession,age,statu…

step7:“模拟量界面”逻辑

文章目录 文章介绍效果图AnalogPage.qml结构图调用 SerialPortHandler.sendData(message); serialporthandler.cpp 文章介绍 之前的6步实现了案例MF的界面设计和串口界面的逻辑设计&#xff0c;本文将实现模拟量界面的逻辑设计 新增功能&#xff1a; 1&#xff09;弹出提示框 …

Mac14.1.2 M1芯片免费读写ntfs硬盘-亲测有效,免费!!!

1. 安装homebrew 打开终端&#xff0c;使用以下命令 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 根据提示逐步完成即可&#xff0c;镜像选择我这里都是保持1的选项。 2. 重启终端 安装完成homebrew后&#xff0c;需…

Java线程池及面试题

1.线程池介绍 顾名思义&#xff0c;线程池就是管理一系列线程的资源池&#xff0c;其提供了一种限制和管理线程资源的方式。每个线程池还维护一些基本统计信息&#xff0c;例如已完成任务的数量。 总结一下使用线程池的好处&#xff1a; 降低资源消耗。通过重复利用已创建的…

第 1 章SwiftUI 简介

在 2019 年的 WWDC 上,Apple 宣布推出一款名为 SwiftUI 的全新框架,令开发者们大吃一惊。该框架不仅改变了开发 iOS 应用的方式,还代表了自 Swift 首次亮相以来 Apple 开发者生态系统最重大的转变。SwiftUI 适用于所有 Apple 平台,包括 iPadOS、macOS、tvOS 和 watchOS,这…

ZSWatch 开源项目介绍

前言 因为时不时逛 GitHub 会发现一些比较不错的开源项目&#xff0c;突发奇想想做一个专题&#xff0c;专门记录开源项目&#xff0c;内容不限于组件、框架以及 DIY 作品&#xff0c;希望能坚持下去&#xff0c;与此同时&#xff0c;也会选取其中的开源项目做专题分析。希望这…

【GD32】08 - IIC(以SHT20为例)

GD32中的IIC 今天来了解一下GD32中的硬件IIC&#xff0c;其实我个人是觉得软件IIC比较方便的&#xff0c;不过之前文章里用的都是软件IIC&#xff0c;今天就算是走出自己的舒适圈&#xff0c;我们来了解了解GD32中的硬件IIC。 我这里用的型号是GD32F407&#xff0c;不同型号的…

多路h265监控录放开发-(14)通过PaintCell自定义日历控件继承QCalendarWidget的XCalendar类

首先创建一个新类XCalendar继承QCalendarWidget类&#xff0c;然后在UI视图设计器中把日历提升为XCalendar&#xff0c;通过这个函数自己设置日历的样式 xcalendar.h #pragma once #include <QCalendarWidget> class XCalendar :public QCalendarWidget { public:XCal…

Java基础(四)——字符串、StringBuffer、StringBuilder、StringJoiner

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

C++编程(四)this指针 常函数 常对象 静态成员

文章目录 一、this指针&#xff08;一&#xff09;概念&#xff08;二&#xff09;显式使用this指针的场景1. 当形参和成员变量名一致时2. 返回对象自身的时候必须要使用this指针3. 在类中销毁一个对象 二、常函数和常对象&#xff08;一&#xff09;常函数1. 概念2. 语法格式 …

Linux Static calls机制

文章目录 前言一、简介二、Background: indirect calls, Spectre, and retpolines2.1 Indirect calls2.2 Spectre (v2)2.3 RetpolinesConsequences 2.4 Static callsHow it works 三、其他参考资料 前言 Linux内核5.10内核版本引入新特性&#xff1a;Static calls。 Static c…

关于摄像头模组中滤光片的介绍

1、问题背景 红外截止滤光片&#xff08;IR CUT Filter&#xff09;是应用在摄像头模组中非常重要的一个器件&#xff0c;因人眼与 coms sensor 对光线各波长的响应不同&#xff0c; 人眼看不到红外光&#xff0c;但 sensor 能感应到&#xff08;如下图是某sensor在各波长下的…

【设计模式-04】原型模式

【设计模式-04】原型模式 1. 概述2. 结构3. 实现4. 案例5. 使用场景6. 优缺点6.1 原型模式的优点6.2 原型模式的缺点 7. 实现深克隆(深拷贝) 1. 概述 原型模式: 用一个已经创建的实例作为原型&#xff0c;通过复制该原型对象来创建一个和原型对象相同的新对象。 2. 结构 原型…

策略模式和状态模式

策略模式 在上下文中携带策略接口作为成员变量&#xff0c;在使用上下文之前需要设置策略setStrategy&#xff08;&#xff09;&#xff0c;然后使用策略接口成员变量来进行策略的执行。 步骤1&#xff1a;定义策略接口 // 策略接口 public interface Strategy {int execut…