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;
    }
}

 

  • 解题结果:

 

 

posted on 2023-01-14 10:18  菜鸟乙  阅读(52)  评论(0编辑  收藏  举报