IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 优先队列 -leetcode-347.前 K 个高频元素 -> 正文阅读

[数据结构与算法]优先队列 -leetcode-347.前 K 个高频元素

347. 前 K 个高频元素

题目描述

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

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

解法选择:

  • 优先队列
    • top k 问题,优先队列是一把好手

优先队列

  • 底层基于堆实现。堆是一种完全二叉树,其父节点大于(或小于)所有子节点,即大根堆(或小根堆)
  • 每次增/删后,保持栈顶元素是 max(或 min)的
    • 仅保持局部是有序的,并不是全部有序

注意:

  • 到底选用大顶堆还是小顶堆?
    • 一开始我就想也没想,题目要求 top k,那“铁定”大顶堆啊。结果,就是直接翻车 WA,调试发现不对
    • 后来一想如果选大顶堆的话,那么,每次出队列弹出的都是max的元素,必然无法使得保留在优先队列中的最终k个是top k(人家都被弹了,还保留个 der 的 top k)
    • 所以,铁定的选择小顶堆。每次将当前元素 value 和当前队头元素对应的 value 比较,如果大于之,则出队;否则,啥也不管

思路:

  1. 使用 map 记录nums中元素出现的个数;
    • key:nums[i];value:nums[i] 出现的次数
  2. 将 map 中前 k 个元素的 key 存入 PriorityQueue;
  3. 将 map 中剩余的 size - k 个元素,与队头元素 peek 比较:
    • 如果 map 中当前元素的 value 大于 peek 在 map 中的 value,则将当前元素 key 入队;
    • 否则,不做任何操作。
  4. 倒序(因为每次取得都是最小的)从小顶堆中取出k个元素,作为最终结果
    • 但题目,其实没有要求输出顺序(扩展一下而已)
class Solution {
    public int[] topKFrequent(int[] nums, int k) { 
		// 记录nums中元素出现的个数
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		for (int i : nums) {
			if (!map.containsKey(i)) {
				map.put(i, 1);
			} else {
				map.put(i, map.get(i) + 1);
			}
		}
		
		// 优先队列(小顶堆k个元素)
		Queue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
			@Override
			public int compare(Integer a, Integer b) {
				return map.get(a) - map.get(b); // // 排序规则(出现次数升序)
			}
		}); 
		
		// 遍历 map,用小顶堆保存频率最大的k个元素
		for (Integer key : map.keySet()) {
			if (queue.size() < k) { // 堆里小于k个元素时候,直接填入
				queue.add(key);
			} else if (map.get(key) > map.get(queue.peek())) { // 核心:保证小根堆里面只有k个元素,并且当前队列元素是最大的
				queue.remove();
				queue.add(key);
			}
		}
		
		// 倒序(因为每次取得都是最小的)从小顶堆中取出k个元素,作为最终结果
        // 但题目,其实没有要求输出顺序(扩展一下而已)
		int cnt = 0; // ans的当前位置
		int[] ans = new int[k]; // 最终答案
		for (int i = k - 1; i >= 0; i--) {
            ans[i] = queue.poll();
        }
		return ans;
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 11:02:29  更:2021-08-02 11:05:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 10:23:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码