0 课程地址
https://coding.imooc.com/lesson/207.html#mid=13745
1 重点关注
1.1 用java自带的优先队列实现取前k个高频元素问题
见3.1
1.2 最小堆和最大堆应用实现优先队列的对比
java自带的优先队列是最小堆,注意3.1 compare和调用compare的变化(和8-7对比)
2 课程内容
3 Coding
3.1 LeetCode 347问题 取前K个高频元素(java自带优先队列实现)
- 需求
给你一个整数数组 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 个高频元素的集合是唯一的
进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/top-k-frequent-elements
- 设计思路:
组成一个元素数量为k的堆,进行上浮下沉,复杂度为O(nlogk),优于O(nlogn)
- coding:
package com.company; import java.util.HashMap; import java.util.Map; import java.util.PriorityQueue; /** * 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 * 使用自己实现的堆(最大堆来实现) * @author weidoudou * @date 2023/1/12 7:34 **/ class Solution { /** * warning 定义这个类,是为了仿照Map进行比较 * @author weidoudou * @date 2023/1/13 6:56 **/ private class MapInnerClass implements Comparable<MapInnerClass>{ private int key,value; public MapInnerClass(int key,int value){ this.key = key; this.value = value; } /** * waring这边好好理解下,这里定义的应该是最小堆(把最大堆组装成了map根据value比较的最小堆),这块 * 用于两部分,1部分是上浮下沉操作,2部分是71行外部比较 * @author weidoudou * @date 2023/1/13 7:17 * @param o 请添加参数描述 * @return int **/ @Override public int compareTo(MapInnerClass o) { if(this.value<o.value){ return -1; }else if(this.value>o.value){ return 1; }else{ return 0; } } } public int[] topKFrequent(int[] nums, int k) { //1 定义内部类,用于实现比较方法 //2 使用自己的优先队列实现这块功能 //2.1 使用映射,频率放入value Map<Integer,Integer> hashMap3 = new HashMap<Integer,Integer>(); for(int i=0;i<nums.length;i++){ if(hashMap3.containsKey(nums[i])){ hashMap3.put(nums[i],hashMap3.get(nums[i])+1); }else{ hashMap3.put(nums[i],1 ); } } //2.2 hashMap循环,取出前k个值放入堆中,大于k的部分和堆顶元素比较 PriorityQueue<MapInnerClass> priorityQueue = new PriorityQueue<>(); //warning,这里不能用for循环 int i = 0,因为映射中的key值无法确定 for(int key: hashMap3.keySet()){ if(priorityQueue.size()<k){ priorityQueue.add(new MapInnerClass(key,hashMap3.get(key))); }else{ MapInnerClass temp = new MapInnerClass(key,hashMap3.get(key)); //如果 堆首的元素 比 外部的元素小,那么进行出堆入堆 if(priorityQueue.peek().compareTo(temp)<0){ priorityQueue.remove(); priorityQueue.add(temp); } } } int [] result = new int[k]; for(int i = 0;i<k;i++){ result[i] = priorityQueue.remove().key; System.out.println(result[i]); } return result; } }
- 解题结果:
诸葛