Leetcode 347.前K个高频元素
Time: 20190910
Type: Medium
题目描述
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
说明:
你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/top-k-frequent-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
通过本题学习处理top k问题的基本思路,本文主要讲两种算法:
- 基于堆的算法
- 基于快速排序分割的算法
基于堆的算法
原则:最大堆求前n小,最小堆求前n大。
- 前k小:构建一个k个数的最大堆,当读取的数小于根节点时,替换根节点,重新塑造最大堆
- 前k大:构建一个k个数的最小堆,当读取的数大于根节点时,替换根节点,重新塑造最小堆[1]^{[1]}[1]
如何理解求top k问题,用堆的思想呢,上面这两句话有助于记住何时使用大顶堆和小顶堆的问题。
可以用一个场景来想这个问题,前段时间看《明日之子》这个综艺节目,其中就用到了top 9的问题模型。如果以名次大小来看,我们需要取的是名次前9小的人,也就是用到了大顶堆,下面我们看为什么。
小屋只提供了9个席位,当每个人完成了比赛后,要根据自己的排名看能否进入到小屋中坐下,能坐下还要决定坐到哪个位置上。
前9个人无论如何都能进入小屋。坐在最外边的是名次最差的,就是小屋里的第九名。这个名次是后来者的比较门槛,如果后来者比TA名次好,TA出去,后来者进去找到自己的位置。反之,后来者出去。
从第十个人开始,TA拿到自己的名次后,要和谁比呢?和坐在靠门外的妹子的名次比,靠门外的妹子的名次是最差的,比最差的好就有了进屋的资格。
相当于大顶堆,用于比较的是最大的值,来的值比它大,则不进去,否则进入。一直到元素用完,得到了top k小的元素。
反过来,小顶堆,存储的top k大的元素,最小的作为比较元素,来的值比它小,则不进去,否则进入。直到元素用完,就得到了top k大的元素。
用一个真实的场景来辅助理解,问题就变得更加清晰了。
从直觉上来说,top k大的,建立小顶堆,比守门员大的可以进。
top k小的,建立大顶堆,比守门员小的可以进。
Python标准库heapq的用法
创建堆
两种建堆方式:
- 使用空列表建堆
使用heapq.heappush(x)
往里面加入元素,这种需要单独开辟一个列表用于存放堆。
- 将列表转为堆
heapq.heapify(lst)
,这种返回值是为None,会in-place将nums改成堆,堆是完全二叉树,元素按照从左往右排列,形成一种逻辑完全二叉树。
弹出堆顶元素
- heapq.heappop()弹出堆顶元素
heapq只实现了小顶堆。
需要注意的是,heapq.nlargest(k, nums)
, heapq.nsmallest(k, nums)
不要求nums
已经符合逻辑上的堆结构。Python太霸道了。
代码
使用heapq的解法
这个解法我感觉自己写的比较繁琐:
import heapq
class Solution:def topKFrequent(self, nums: List[int], k: int) -> List[int]:# 先统计数字出现频率dic = {}for num in nums:if dic.get(num) == None:dic[num] = 1else:dic[num] += 1print("dic: ", dic)heap = []# 取出频次并建堆for num in dic.values():heapq.heappush(heap, num)print("heap: ", heap)res = []lst_values = list(dic.values())lst_keys = list(dic.keys())for num in heapq.nlargest(k, heap):index = lst_values.index(num)res.append(lst_keys[index])lst_values.pop(index)lst_keys.pop(index)return res
求出词频后,对频次建堆,注意频次是可以相同的,所以用一个循环,遍历词频的top k大,然后根据value找key,注意是将key和value都转化为列表,用下标求解。因为词频可以相同,所以用过的就删掉,否则.index()
时会找到已经用过的元素。
参考
0: 程序员小吴的题解
1: xxinjiee的题解
Leetcode 347.前K个高频元素相关推荐
- LeetCode——347. 前 K 个高频元素【最小堆实现】
LeetCode--347. 前 K 个高频元素[最小堆实现] 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素.你可以按 任意顺序 返回答案. 示例1: 输入: n ...
- Leetcode 347. 前 K 个高频元素
Leetcode 347. 前 K 个高频元素 1.问题分析 2.问题解决 3.总结 1.问题分析 题目链接:https://leetcode-cn.com/problems/top-k-freque ...
- Java实现 LeetCode 347 前 K 个高频元素
347. 前 K 个高频元素 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输 ...
- LeetCode 347. 前 K 个高频元素(C++)*
该题在不考虑时间复杂度的要求下,可以使用哈希表来存储元素的次数,或者使用排序算法:为了提高算法的效率,考虑使用优先队列来实现大根堆. 1.题目如下: 给你一个整数数组 nums 和一个整数 k ,请你 ...
- LeetCode 347. 前 K 个高频元素(哈希/优先队列)
文章目录 1. 题目 2. 解题 2.1 哈希 2.2 优先队列 1. 题目 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], ...
- Leetcode 347. 前K个高频元素 解题思路及C++实现
方法一:最小堆 解题思路: 先使用一个unordered_map来遍历nums容器,得到每个元素对应的频数. 再使用最小堆,对unordered_map中的频数进行遍历,得到k个最大的频数对应的< ...
- 【LeetCode】【HOT】347. 前 K 个高频元素(哈希表+优先队列)
[LeetCode][HOT]347. 前 K 个高频元素 文章目录 [LeetCode][HOT]347. 前 K 个高频元素 package hot;import java.util.Arrays ...
- 模拟卷Leetcode【普通】347. 前 K 个高频元素
347. 前 K 个高频元素 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素.你可以按 任意顺序 返回答案. 示例 1: 输入: nums = [1,1,1,2,2 ...
- 力扣347 前 K 个高频元素 -- JS
347. 前 K 个高频元素 - 力扣(LeetCode) (leetcode-cn.com) 一:使用对象进行解题,对象的属性为给定数组的元素,属性值为给定数组元素出现的次数: 二:把对象转成数组, ...
最新文章
- vscode 显示最近打开的folder_vscode报错Module #x27;pygal#x27; has no #x27;Bar#x27; Member...
- python 序列化_python之序列化
- python中for和while区别_Python学习第九篇——while和for的区别
- 自动化测试 之 “好用例、坏用例”
- java 排队实现_实验排队功能实现(JAVA)
- 基于JAVA+SpringMVC+Mybatis+MYSQL的酒店预订管理系统
- Geant4学习一:写一个简单程序
- CSS手写向下小三角(极简代码)
- webstorm打开项目不显示文件夹
- ASIFT算法过程实现 --- 配置避坑指南
- 另一大短视频网址无水印下载,爱了吗?
- tiktok 手机验证_TikTok经过验证的硅谷正在创新
- 计算机关机管理软件,电脑自动关机软件
- 苹果电脑怎么设置和修改开机密码?
- 周大福守护一生 | 在520奔赴一场终身浪漫的约会
- NBA篮球图文直播室之数据排行榜
- 在WDCP控制面板怎么安装SSL证书
- 久等了 Snoop Dogg 虚拟化身系列 NFT 来了
- 股票基础知识 电子书下载
- 【Python3 爬虫学习笔记】用PySpider爬取虎嗅网并进行文章分析
热门文章
- Yolov2 训练时anchor是如何使用的?build_target
- 机器学习基石PLA相关
- 【个人网站搭建教程】阿里云服务器+宝塔+wordpress
- c++访问私有(private)成员变量的常用方法
- word拼写检查自定义词典下载_取消或开启Word拼写检查和语法(去掉红波浪线)...
- .net mysql字符串截取_MySQL 字符串拆分操作(含分隔符的字符串截取)
- python的chr可以转换中文吗,chr()在python中怎么实现编码的转换
- python随机生成中文句子_python – 如何使用NLTK从诱导语法中生成句子?
- python 生成nc文件_Python生成器处理大文本文件的代码
- 罗定职业技术学院计算机考试二级,2018年罗定职业技术学院五年一贯制单独招生术科考试成绩.PDF...