【优先级队列】前K个高频单词 && 数据流的中位数


在这里插入图片描述

692. 前K个高频单词

692. 前K个高频单词

​ 给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。

​ 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。

示例 1:

输入: words = ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。
    注意,按字母顺序 "i" 在 "love" 之前。

示例 2:

输入: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4
输出: ["the", "is", "sunny", "day"]
解析: "the", "is", "sunny" 和 "day" 是出现次数最多的四个单词,
    出现次数依次为 4, 3, 2 和 1 次。

注意:

  • 1 <= words.length <= 500
  • 1 <= words[i] <= 10
  • words[i] 由小写英文字母组成。
  • k 的取值范围是 [1, 不同 words[i] 的数量]

**进阶:**尝试以 O(n log k) 时间复杂度和 O(n) 空间复杂度解决。


解题思路:哈希表 + 优先级队列

​ 这道题很明显还是要使用 topk 问题的处理方式来解决,也就是使用堆来解决,只不过这道题稍微要多处理其它的内容!

​ 首先因为需要按单词出现频率由高到低排序,那么就需要统计单词的出现频率,就可以 使用哈希表来统计

​ 然后将哈希表内容按 topk 模式进行处理,这里有细节,就是因为我们既要获得堆中的字符串,又得根据频次来维护堆,所以优先级队列存放的是一个键值对 pair<string, int>,还有就是因为==频次从高到小排序,那么我们就要建立一个小根堆==,所以要自己写一个比较器 compare,这里用仿函数为例!

​ 在比较器中还要特别注意一个细节,我们需要特殊判断一下次数相等的情况,此时要根据字典顺序从低到高排序,所以 对于字典序列要搞个大堆才行,和频次是相反的,一定要弄清楚比较器中大于和小于的区别,大于表示的是建小堆,小于表示的是建大堆,别搞错了!

​ 接着就是一个循环,先将哈希表中的键值对插入,然后判断一下优先级队列是否超过了 k 个元素,是的话直接让堆顶 pop 掉即可,因为我们建立的堆是与序列相反的,那么 pop 的就是不满足要求的!以此类推,直到哈希表遍历完毕!

​ 最后就是将堆中元素取出,然后放到数组中返回,注意因为堆中次序和返回的次序是相反的,所以我们要先逆序,再返回结果!

struct compare
{
   
    bool operator()(pair<string, int>& p1, pair<string, int>& p2)
    {
   
        // 特殊判断一下次数相等的情况
        if(p1.second == p2.second)
            return p1.first < p2.first; // 注意细节,字典顺序是从低到高,所以字典要搞个大堆才行,和频次相反
        return p1.second > p2.second;
    }
};

class 
<think>好的,我现在需要帮助用户了解优先队列在软考中的相关内容,包括实现和应用。首先,我需要明确用户的需求:他们可能在准备软考,特别是软件设计师考试,所以需要知道优先队列在考试中的重点、实现方式以及应用场景。 首先,我应该回顾优先队列的基本概念。优先队列是一种抽象数据类型,支持插入元素和按优先级取出元素。它的特点是不遵循严格的先进先出,而是根据优先级,通常是最高优先级先出。这一点和普通队列不同,普通队列是FIFO的,而栈是LIFO的。用户可能已经了解队列和栈的基础,所以需要对比说明优先队列的不同之处,引用已有的引用内容,比如引用[3]和[4]提到的队列和栈的特点。 接下来,实现方式。优先队列通常可以通过堆(尤其是二叉堆)来实现,也可以用有序数组或链表,但堆的效率更高。软考中可能会考察堆的结构和操作,比如插入和删除的时间复杂度。需要解释堆的结构,比如完全二叉树,以及如何用数组表示堆。这部分可能需要代码示例,比如用Python实现一个优先队列,但用户提到的是软考,可能更关注理论而不是具体代码,不过代码示例有助于理解。 然后,应用场景。优先队列常用于任务调度、哈夫曼编码、Dijkstra算法等。这些应用在软考中可能出现,比如在算法题或选择题中涉及。需要结合引用[2]提到的图结构应用,比如路径规划中的Dijkstra算法使用优先队列来选择最短路径。 软考中的相关考点可能包括优先队列的特性、实现方式、时间复杂度,以及与其他数据结构的比较。比如,比较堆和有序数组在插入和删除操作上的性能差异。同时,可能涉及优先队列在算法中的应用,比如最小生成树或最短路径算法。 用户可能还需要知道如何准备这部分内容,比如参考真题和模拟题,动手实践实现优先队列,结合引用[1]提到的备考方法。此外,构建知识体系,将优先队列与图、树等结构联系起来,形成完整的认知框架。 需要确保回答结构清晰,分点说明,包括基本概念、实现原理、应用场景和软考重点。同时,引用已有的引用内容,比如引用[3]和[4]来对比队列和栈,引用[2]说明图的应用中的优先队列使用。 最后,生成相关问题,帮助用户进一步学习,比如堆的实现细节、复杂度分析,或者与其他数据结构的比较,以及具体的算法应用。 总结,回答应包括: 1. 优先队列的基本概念和特点 2. 实现方式(堆、有序数组等) 3. 应用场景(任务调度、算法应用等) 4. 软考中的考点和备考建议 5. 相关问题</think>### 优先队列在软考中的相关内容与实现 #### 一、基本概念与特性 优先队列(Priority Queue)是一种抽象数据类型,其**元素按优先级排序**,优先级最高的元素最先被移除[^3]。与普通队列(FIFO)和栈(LIFO)不同,它通过元素的优先级动态调整顺序。例如: - **入队操作**:插入元素时自动调整顺序。 - **出队操作**:总是移除当优先级最高的元素。 #### 二、实现原理 软考中常考察优先队列的**实现方式及其时间复杂度**: 1. **堆(Heap)**: - 二叉堆是最常见的实现方式,分为最大堆(父节点值 ≥ 子节点)和最小堆。 - 插入操作(`push`):时间复杂度为 $O(\log n)$,元素上浮调整堆结构。 - 删除操作(`pop`):时间复杂度为 $O(\log n)$,将末尾元素移到堆顶后下沉调整。 - 示例代码(Python): ```python import heapq pq = [] heapq.heappush(pq, 3) # 插入元素 heapq.heappush(pq, 1) print(heapq.heappop(pq)) # 输出1(最小堆) ``` 2. **有序数组/链表**: - 插入时维护顺序,时间复杂度为 $O(n)$。 - 出队时直接取首元素,时间复杂度为 $O(1)$。 - **适用场景**:元素数量较少或频繁出队操作。 #### 三、应用场景(软考高频考点) 1. **任务调度**:操作系统进程调度中按优先级分配CPU资源。 2. **图算法**: - **Dijkstra最短路径算法**:优先队列用于快速获取当最短路径节点[^2]。 - **哈夫曼编码**:合并频率最小的节点生成最优二叉树。 3. **数据流处理**:如实时获取数据流中的中位数或Top-K元素。 #### 四、软考中的核心考点 1. **时间复杂度与实现选择**:堆实现优于有序数组(插入$O(\log n)$ vs. $O(n)$)[^4]。 2. **堆的调整过程**:上浮(`sift_up`)和下沉(`sift_down`)的具体操作步骤。 3. **与其他结构的对比**:如栈(LIFO)和普通队列(FIFO)的特性差异[^4]。 #### 五、备考建议 1. **实践代码**:手动实现堆的插入、删除操作,理解调整逻辑。 2. **结合真题**:分析软考中优先队列在算法设计题中的应用(如Dijkstra算法实现)。 3. **知识串联**:将优先队列与树、图等结构结合,形成系统化认知[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

利刃大大

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

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

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

打赏作者

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

抵扣说明:

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

余额充值