天天看点

LeetCode 347:前k个高频元素

LeetCode 347:前k个高频元素

    • 题目描述
    • 解题思路
    • 代码实现
    • 总结

题目描述

给定一个非空的整数数组,返回其中出现频率前 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 是数组的大小。

解题思路

想到可以用hashmap以每个元素为key统计,各个元素出现的频次,再构建一个小顶堆用来存储前k个高频的元素,遍历数组元素,在小顶堆存储个数小于k时,按序添加,大于k时,比较堆顶元素出现的频次和遍历元素出现的频次,如果堆顶元素频次小于遍历元素的,那么将堆顶元素弹出后,再将新元素加入堆中!!!

代码实现

去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的

代码片

.

import java.util.*;

public class topKthEle {
    //前k个高频元素
    public List<Integer> topKFrequent(int[] nums,int k){//acc: 24ms 53%
        HashMap<Integer,Integer> map = new HashMap<>();
        for (int num:nums){  //统计nums数组中,各数字出现的频次
            if (map.containsKey(num)){
                map.put(num,map.get(num)+1);
            }else {
                map.put(num,1);
            }
        }

        PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return map.get(o1)-map.get(o2);
            }
        });

        for (Integer key:map.keySet()){ //将出现频次最高的k个元素装入小顶堆中
            if (pq.size()<k){
                pq.add(key);
            }else if (map.get(key)>map.get(pq.peek())){
                pq.remove();
                pq.add(key);
            }
        }

        List<Integer> res=new ArrayList<>();
        while (!pq.isEmpty()){
            res.add(pq.remove());
        }
        return res;
    }
    public static void main(String[] args) {
        topKthEle test=new topKthEle();
        int[] nums={1,3,2,1,3,1,5};
        List<Integer> list=test.topKFrequent(nums,2);
        System.out.println(list);
    }
}

           

总结

本题来源于Leetcode中 归属于堆类型题目。

同许多在算法道路上不断前行的人一样,不断练习,修炼自己!

如有博客中存在的疑问或者建议,可以在下方留言一起交流,感谢各位!

觉得本博客有用的客官,可以给个赞鼓励下! 嘿嘿