java数据结构与算法刷题-----LeetCode347. 前 K 个高频元素

Java实现LeetCode第347题:求前K个高频元素 本文还有配套的精品资源,点击获取 简介:LeetCode第347题要求找出数组中出现频率最高的前K个元素。解决这个问题涉及到数据结构和算法知识,特别是哈希表和优先队列的使用。通过构建HashMap记录元素出现频率,并使用优先队列维护频率排序,最终提取出所需元素。Java解决方案将通过具体的代码实现加深理解,并提升程序员处理相关问题的能力。 1. LeetCode第... 阅读详情
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.youkuaiyun.com/grd_java/article/details/123063846

在这里插入图片描述

1. 法一:桶排序

解题思路:时间复杂度O(n),空间复杂度O(n)
  1. 我们先通过hash表,将每个元素的出现频率统计出来
  2. 根据出现频率进行桶排序
  3. 那么越后面的桶的元素,出现次数越多。所以从后向前遍历桶,将桶中的元素依次取出
  4. 题目要求取k个,那就取k个为止,放入结果数组中。
    在这里插入图片描述
代码

在这里插入图片描述

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        // 1. 准备计数排序的数组,也就是hash表,这里用数组来充当hash表,做题时,处理速度要优于使用HashMap,
        //注意实际工作场景中,使用线程安全的HashMap容器,而不用使用数组来作为hash
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for(int num: nums) {
            if(num > max)
                max = num;
            if(num < min)
                min = num;
        }
        //创建可以容纳数组中所有取值的hash表,用下标索引代表nums数组中元素值
        if (max == min) return new int[] {nums[0]};
        int [] count = new int[max - min + 1];
        int bucketLength = 0;//桶排序,桶的数量,我们要对出现频率桶排序,所以,最大的出现频率+1就是桶的数量
        for(int num: nums) {//hash数组下标从0开始,下标0代表nums中的最小值,因此每个元素存储时,要进行-min+1
            count[num - min]++;
            bucketLength = bucketLength<count[num-min]?count[num-min]:bucketLength;//最大出现频率
        }

        // 2. 将计数排序数组转化为 存放频率的桶,对hash表中存储的元素出现频率,进行桶排序
        List<Integer> [] bucket = new ArrayList[bucketLength + 1];//最大出现频率+1为桶的数量
        //进行桶排序
        for(int i = 0; i < count.length; i++) {
            if(count[i] > 0) {
                if(bucket[count[i]] == null) {//每个桶都是一个链表
                    bucket[count[i]] = new ArrayList();
                }
                bucket[count[i]].add(i + min);//存放时,不在存放下标,而是元素值本身
            }
        }
        // 3. 从高频率往低频率遍历(从后往前遍历),构造结果数组
        int [] res = new int[k];
        for(int i = bucket.length - 1, j = 0; j < k && i >= 0; i--) {
            List<Integer> fdata = bucket[i];//获取当前桶中的所有结点
            if(fdata != null) {//如果有结点
                int size = fdata.size();
                //将当前出现频率的结点,依次放入res结果数组中
                // for(int index = size - 1; index >= 0; index--) {
                //     res[j++] = fdata.get(index);
                // }//桶内无论怎么输出,都无所谓
                for(int index = 0; index <= size-1; index++) {
                    res[j++] = fdata.get(index);
                }
            }
        }
        return res;
    }
}

2. 法二:小根堆(更具实战意义)

此方法更推荐实际工作中使用,因为桶排序的不确定因素有很多,很可能出现桶的数量过多,从而浪费大量空间的情况。

解题思路
  1. 和桶排序基本类似。只不过将桶排序,换成了堆排序(小根堆)
  2. 先hash统计出现次数
  3. 通过优先级队列,实现小根堆。保证堆顶永远是最少出现次数。
  4. 先插入k个元素到小根堆。因为题目要求返回k个出现频率最高的
  5. 之后如果还有元素,和堆顶进行比较,如果比堆顶小,就舍弃。否则取出堆顶元素,让当前新元素入堆。
代码

在这里插入图片描述

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        //建立hash映射
        Map<Integer, Integer> occurrences = new HashMap<Integer, Integer>();
        for (int num : nums) {
            occurrences.put(num, occurrences.getOrDefault(num, 0) + 1);
        }

        // int[] 的第一个元素代表数组的值,第二个元素代表了该值出现的次数
        //优先级队列,就是堆。默认是大根堆
        PriorityQueue<int[]> queue = new PriorityQueue<int[]>(new Comparator<int[]>() {//改为小根堆
            public int compare(int[] m, int[] n) {//出现次数谁高,谁优先级就高,会最优先出堆
                //n表示堆顶,m是新插入
                //compare方法,如果返回值 >0 那么m放入n后面
                //如果m更大,m就插入到n的下面,n继续是堆顶,从而实现小根堆
                return m[1] - n[1];//优先级高的先出堆。也就是它们在堆的最下面,最优先出堆
                //n表示堆顶,m是新插入,如果返回值 < 0 m就作为新的堆顶,从而实现大根堆
                //如果m更大,n - m必然小于0, 那么m成为新的堆顶
                //return n[1] - m[1];
            }
        });
        //构建小根堆。堆中元素=k.检查堆顶,和当前想要入堆的出现次数,
        //因为我们只需要k个出现频率最高的,所以已经有k个了,后面想入堆的需要进行判断
        //如果想入堆的出现次数更高,就弹出堆顶,让其入堆。如果没有堆顶大,就舍去想入堆的
        //而如果堆中元素 < k,说明还没有凑够题目要求的k个元素,无脑入堆
        for (Map.Entry<Integer, Integer> entry : occurrences.entrySet()) {
            int num = entry.getKey(), count = entry.getValue();
            if (queue.size() == k) {//如果堆中已经有k个元素
                if (queue.peek()[1] < count) {//看看堆顶是否 < 当前元素
                    queue.poll();//如果小,说明当前元素出现频率更高,那么堆顶不要了,新元素入堆
                    queue.offer(new int[]{num, count});
                }
            } else {//如果堆中没有够k个,无脑入堆
                queue.offer(new int[]{num, count});
            }
        }
        int[] ret = new int[k];//答案数组
        for (int i = 0; i < k; ++i) {
            ret[i] = queue.poll()[0];//依次出堆
        }
        return ret;
    }
}
单端反激电源的RCD钳位电路吸收设计 反激电源尖峰电压和特点: 反激开关电源主要适用于中小功率<100W的电源设计中,特点是电路简单、成本低、可靠性高、宽稳压范围、转换效率PF高。但是由于本身变压器的漏感和其他参数的影响,变压器在高速开关关断瞬间会产生很大的尖峰电压,截止时产生的尖峰电压是由电路中的储能元件释放的电流引起的突变,过高的尖峰电压会影响开关管的正常工作,需要对尖峰电压采取措施抑制尖峰电压。 如上图所示,尖峰电压的钳位抑制方式有很多种。 TVS成本偏高,属于硬件导通,元件的可靠性较差,在低电压工作效果不理想。 RCD回路吸收 阅读详情

相关推荐

Windows 10下用Python 3搞定Android源码下载:最新repo工具避坑指南

本文详细介绍了在Windows 10系统上,使用Python 3和官方最新repo工具下载Android源码的完整流程。文章提供了从Git安装、环境配置到repo工具初始化、同步加速及常见错误排查的避坑指南,帮助开发者高效搭建稳定的源码下载环境。

weixin_29266749的博客 436

java刷算法题 常用的一些方法

1. 输入输出类 Scanner sc = new Scanner(System.in); String input = sc.nextLine(); System.out.println(input); 2. 常用的数据结构 2.1栈 Stack stack = new Stack<>(); System.out.println(stack.empty()); System.out.println(stack.size()); stack.push(1); stack.push(2);

克豪的博客 1037

从驱动编译到数据传输:RK3588与FPGA的PCIe通信实战解析

本文详细解析了RK3588与FPGA通过PCIe通信的实战过程,涵盖驱动编译、数据传输及性能优化等关键步骤。通过XDMA驱动实现高效DMA传输,适用于视频处理、数据采集等高性能场景,帮助开发者快速掌握嵌入式系统中的PCIe通信技术。

weixin_29214691的博客 528

算法刷题Java技巧

算法刷题技巧

范大的博客 1016

静态时序分析(Static Timing Analysis, STA):简介及内容导航

静态时序分析(简称STA)是用来验证数字设计时序的技术之一,另外一种验证时序的方法是时序仿真,时序仿真可以同时验证功能和时序。“时序分析”这个术语就是用来指代“静态时序分析“或”时序仿真“这两种方法之一,简单来说,时序分析的目的就是为了解决设计中的各种时序问题。STA被称为静态的原因是其对于设计的分析是静态地执行的,并不依赖于施加在输入端口上的激励。相比之下,时序仿真则可以被视作动态地执行对设计的分析,具体过程描述如下:施加一组激励,观察在这组激励下电路行为是否符合要求,然后换一组激。

Starry__的博客 1997

九齐NY8A051F低功耗模式全解析:从待机到休眠的省电实战

本文全面解析台湾九齐NY8A051F MCU的低功耗模式,从待机到休眠的省电实战技巧。通过实测数据展示四种工作模式的电流消耗差异,提供模式切换的标准流程和唤醒时序优化策略,并分享外围电路省电设计和低电压检测的实战应用,帮助开发者实现物联网设备的超长续航。

weixin_30839881的博客 413

LeetCode 347. 前K个高频元素 692.前K个高频单词

题目: 分析: 这题要求从所给数组中筛选出出现频率前k高的元素,因此需要统计每个数出现的次数,使用HashMap记录数据和它们出现的频次,读到的数如果在Map中不存在,则添加到Map中并记录频次为1,一旦第二次读到,就把计数加一。 HashMap&amp;lt;Integer, Integer&amp;gt; map=new HashMap&amp;lt;&amp;gt;(); for(int i=0;i&amp;lt...

马一凡的博客 247

MultiOTP Credential Provider避坑指南:从安装到RDP双因素认证的全流程解析

本文详细解析了MultiOTP Credential Provider从安装到实现RDP双因素认证(MFA)的全流程,重点分享了Docker部署、Active Directory集成及网络级认证(NLA)兼容性等环节的实战避坑经验,旨在帮助运维人员高效、稳定地部署离线双因素认证方案,提升Windows远程桌面安全性。

weixin_29255731的博客 646

每日一题:Leetcode-347 前K个高频元素

力扣题目解题思路java代码。

LIUCHANGSHUO的博客 1144

热更新方案 HybridCLR 学习教程 |(一)原理及准备工作

前面文章介绍了热更新相关的知识,包括使用xLua实现热更新实战等 那本文就来介绍一下 热更新方案 HybridCLR(代号wolong,原huatuo)和基本使用方法。 若是想了解更多关于HybridCLR的东西也可以去 官网 详细查阅。

努力前行,总会成为自己心中的那道光 2万+

【基础演练】Playwright 极简复习:作为 AI-RPA 底座的 Playwright 核心用法

摘要: 2026年,Playwright已从测试工具升级为AI-RPA标准执行底座,周下载量超3300万,被browser-use等AI Agent项目广泛采用。其核心架构通过Playwright Server实现多浏览器协议适配,支持远程连接与高并发隔离(BrowserContext)。自动等待机制显著提升稳定性,但高频交互场景可能需直接使用CDP协议。Playwright凭借跨浏览器兼容性、轻量级隔离和微软官方支持,成为测试、RPA和AI Agent领域的事实标准,未来将主导对话式自动化市场。

ZDQ58818的博客 238

[C++]Leetcode超高效刷题顺序及题目详解笔记(持续更新中)

一.引言 博主最近在LeetCode上用C++练习。一路走来踩过一些坑,做了一些总结和笔记,分享给需要的人。 LeetCode网址:https://leetcode.com/ LeetCode中文版:https://leetcode-cn.com/ 二.刷题指南 LeetCode 是一个非常棒的平台,收集了许多公司的面试题目。相对其他平台而言,有着下面的几个优点: 题目全部来自业内大公司的真实面试不用处理输入输出 精力全放在解决具体问题上题目有丰富的讨论 可以参考别人的思路精确了解自己代码在所有提交代码中

cpb____的博客 2万+

不会精准对比前人研究写“讨论与对比”段落?教你用ChatGPT辅助,直接让这部分提升一个档次(附提示词指令)

一个我觉得很有效的做法是,选取几篇具有代表性的文献,从研究方法、变量设置或结论方面进行对照分析,并指出本研究在哪些方面进行了补充或修正。除了简单说“提出了新的方法”或“首次应用某模型”,更需要说明这一做法在结果解读、研究设计或理论拓展上的具体意义,最好能够与现有研究进行比较,形成明确的差异化描述。段落应包含:研究结果解释、与前人研究对比、研究贡献、局限性反思,并在结尾提出未来研究的可能方向。讨论与对比部分一般位于文献综述、研究讨论或结果分析的后面,目的是对比已有研究,突出自己研究的价值与新意。

智能AI让学术科研更容易 171

leetcode【栈与队列—中等】 347.前 K 个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], k = 1 输出: [1] 提示: 1 <= nums.length <= 105 k 的取值范围是 [1, 数组中不相同的元素的个数] 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

每个人都是独一无二的,把握好自己的节奏,跟着自己的心走。 2791

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

【LeetCode 热题 100】347. 前 K 个高频元素——(解法一)排序截取

Problem:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

最短的捷径就是绕远路,绕远路才是我的最短捷径。 1297

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

【LeetCode刷题日记】347.前k个高频元素

摘要:本文介绍了两种基于堆结构(优先级队列)的算法实现,用于解决"返回数组中出现频率前k高的元素"问题。方法一使用大顶堆,对所有元素进行排序后取前k个;方法二采用更高效的小顶堆,仅维护k个元素,通过不断替换堆顶来保留高频元素。两种方法都先用哈希表统计元素频率,再通过不同堆结构进行排序,最终时间复杂度优于O(nlogn)。小顶堆实现更为优化,仅需O(nlogk)时间复杂度,适合处理大规模数据。

任岁月风干理想再也找不回真的我 1072

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【LeetCode 热题 100】347. 前 K 个高频元素——(解法二)最大堆

Problem:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

最短的捷径就是绕远路,绕远路才是我的最短捷径。 1226

【Leetcode hot 100】347.前K个高频元素

摘要 题目要求从整数数组中找出出现频率前k高的元素。解法一使用最小堆(优先队列)统计频率并维护大小为k的堆,时间复杂度为O(n log k)。解法二采用桶排序,构建频率桶后从高频到低频收集元素,时间复杂度优化至O(n)。两种方法均满足题目要求,其中桶排序效率更优。测试示例验证了算法的正确性。

专注Java和MySQL领域知识分享 814

LeetCode 347:前k个高频元素

LeetCode 347:前k个高频元素题目描述解题思路代码实现总结 题目描述 给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], k = 1 输出: [1] 说明: 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。 你...

香农三定律的博客 238

力扣347:前k个高频元素---leetcode347:Top K Frequent Elements

力扣347:前k个高频元素---leetcode347:Top K Frequent Elements 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

xxxnnn1991的博客 393

代码随想录-Day13 | LeetCode239. 滑动窗口最大值、LeetCode347.前 K 个高频元素

栈模型可以想象成一个顶端开口的瓶子,其特性是先进后出,后进先出。从随想录中针对栈的题目,其实不难发现由于这个后进先出的特性,非常适合元素的匹配问题,比如说LeetCode20. 有效的括号:寻找我们左括号相同类型的右括号,我们直接从栈顶元素去对比;还有LeetCode1047. 删除字符串中的所有相邻重复项:我们在遍历字符串的时候,一旦发现当前所遍历的元素和栈顶元素重复,直接从栈顶pop进而达到删除重复项的目的。

weixin_45923460的博客 1005

LeetCode 347. 前K个高频元素 - 哈希计数、堆与桶排序详解

题目描述:给定一个整数数组 nums 和整数 k,请返回出现频率前 k 高的元素集合。若存在频率相同的元素,返回任意顺序均可。要求尽可能低的时间复杂度与合理的空间复杂度。原题链接:https://leetcode.cn/problems/top-k-frequent-elements/难度等级:Medium相关标签:数组、哈希表、堆(优先队列)、桶排序、排序| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 | 适用场景 |

m0_52114506的博客 825

347.前 K 个高频元素(栈与队列的算法题)

【摘要】题目要求从非空整数数组中找出出现频率前k高的元素。核心思路是:1)用哈希表统计元素频率;2)使用小顶堆维护前k高频元素。具体实现:先遍历数组统计频率存入哈希表,然后建立大小为k的小顶堆,遍历哈希表将元素加入堆,当堆大小超过k时移除堆顶最小频率元素,最终堆中即为前k高频元素。该方法时间复杂度优于O(nlogn),关键点在于正确选择小顶堆而非大顶堆来优化效率。文章还对比了Java中PriorityQueue的使用方法、常见场景及注意事项,强调要根据具体需求选择适当的堆结构。

m0_68880377的博客 708

算法刷题day13 | 239. 滑动窗口最大值、347.前 K 个高频元素

寻找前k个最大元素流程如图所示:(图中的频率只有三个,所以正好构成一个大小为3的小顶堆,如果频率更多一些,则用这个小顶堆进行扫描)

Evans857的博客 1020

代码随想录刷题|LeetCode 239. 滑动窗口最大值 347.前 K 个高频元素

队列的用法:单调队列、优先级队列

symdunstaz的博客 808

LeetCode347 -- 前k个高频元素

题目描述 给定一个非空的整数数组,返回其中出现频率前k高的元素。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], k = 1 输出: [1] package leetcode_n; import java.util.ArrayList; import java.util.Hash...

qq_41814874的博客 148
上一篇: java数据结构与算法刷题-----LeetCode239. 滑动窗口最大值
下一篇: java数据结构与算法刷题-----LeetCode155. 最小栈
ydenergy_殷志鹏
博客等级 码龄7年 5887粉丝 543原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值