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个高频元素相关推荐

  1. LeetCode——347. 前 K 个高频元素【最小堆实现】

    LeetCode--347. 前 K 个高频元素[最小堆实现] 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素.你可以按 任意顺序 返回答案. 示例1: 输入: n ...

  2. Leetcode 347. 前 K 个高频元素

    Leetcode 347. 前 K 个高频元素 1.问题分析 2.问题解决 3.总结 1.问题分析 题目链接:https://leetcode-cn.com/problems/top-k-freque ...

  3. Java实现 LeetCode 347 前 K 个高频元素

    347. 前 K 个高频元素 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输 ...

  4. LeetCode 347. 前 K 个高频元素(C++)*

    该题在不考虑时间复杂度的要求下,可以使用哈希表来存储元素的次数,或者使用排序算法:为了提高算法的效率,考虑使用优先队列来实现大根堆. 1.题目如下: 给你一个整数数组 nums 和一个整数 k ,请你 ...

  5. LeetCode 347. 前 K 个高频元素(哈希/优先队列)

    文章目录 1. 题目 2. 解题 2.1 哈希 2.2 优先队列 1. 题目 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], ...

  6. Leetcode 347. 前K个高频元素 解题思路及C++实现

    方法一:最小堆 解题思路: 先使用一个unordered_map来遍历nums容器,得到每个元素对应的频数. 再使用最小堆,对unordered_map中的频数进行遍历,得到k个最大的频数对应的< ...

  7. 【LeetCode】【HOT】347. 前 K 个高频元素(哈希表+优先队列)

    [LeetCode][HOT]347. 前 K 个高频元素 文章目录 [LeetCode][HOT]347. 前 K 个高频元素 package hot;import java.util.Arrays ...

  8. 模拟卷Leetcode【普通】347. 前 K 个高频元素

    347. 前 K 个高频元素 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素.你可以按 任意顺序 返回答案. 示例 1: 输入: nums = [1,1,1,2,2 ...

  9. 力扣347 前 K 个高频元素 -- JS

    347. 前 K 个高频元素 - 力扣(LeetCode) (leetcode-cn.com) 一:使用对象进行解题,对象的属性为给定数组的元素,属性值为给定数组元素出现的次数: 二:把对象转成数组, ...

最新文章

  1. vscode 显示最近打开的folder_vscode报错Module #x27;pygal#x27; has no #x27;Bar#x27; Member...
  2. python 序列化_python之序列化
  3. python中for和while区别_Python学习第九篇——while和for的区别
  4. 自动化测试 之 “好用例、坏用例”
  5. java 排队实现_实验排队功能实现(JAVA)
  6. 基于JAVA+SpringMVC+Mybatis+MYSQL的酒店预订管理系统
  7. Geant4学习一:写一个简单程序
  8. CSS手写向下小三角(极简代码)
  9. webstorm打开项目不显示文件夹
  10. ASIFT算法过程实现 --- 配置避坑指南
  11. 另一大短视频网址无水印下载,爱了吗?
  12. tiktok 手机验证_TikTok经过验证的硅谷正在创新
  13. 计算机关机管理软件,电脑自动关机软件
  14. 苹果电脑怎么设置和修改开机密码?
  15. 周大福守护一生 | 在520奔赴一场终身浪漫的约会
  16. NBA篮球图文直播室之数据排行榜
  17. 在WDCP控制面板怎么安装SSL证书
  18. 久等了 Snoop Dogg 虚拟化身系列 NFT 来了
  19. 股票基础知识 电子书下载
  20. 【Python3 爬虫学习笔记】用PySpider爬取虎嗅网并进行文章分析

热门文章

  1. Yolov2 训练时anchor是如何使用的?build_target
  2. 机器学习基石PLA相关
  3. 【个人网站搭建教程】阿里云服务器+宝塔+wordpress
  4. c++访问私有(private)成员变量的常用方法
  5. word拼写检查自定义词典下载_取消或开启Word拼写检查和语法(去掉红波浪线)...
  6. .net mysql字符串截取_MySQL 字符串拆分操作(含分隔符的字符串截取)
  7. python的chr可以转换中文吗,chr()在python中怎么实现编码的转换
  8. python随机生成中文句子_python – 如何使用NLTK从诱导语法中生成句子?
  9. python 生成nc文件_Python生成器处理大文本文件的代码
  10. 罗定职业技术学院计算机考试二级,2018年罗定职业技术学院五年一贯制单独招生术科考试成绩.PDF...