leetcode347--数组中前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 是数组的大小。
 * 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
 * 你可以按任意顺序返回答案。
 */
方法一:将元素和频率封装为一个内部类
package com.study.MaxHeap.TopKFrequentElements347;

import java.util.PriorityQueue;
import java.util.TreeMap;


class Solution {
    private static class Freq implements Comparable<Freq>{
        private int value;
        private int freq;
        public Freq(int value, int freq) {
            this.value = value;
            this.freq = freq;
        }
        @Override
        public int compareTo(Freq other) {
            if (this.freq > other.freq)
                return 1;
            else if (this.freq < other.freq)
                return -1;
            else
                return 0;
        }
    }
    public static int[] topKFrequent(int[] nums, int k) {

        TreeMap<Integer, Integer> map = new TreeMap<>();
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(nums[i]))
                map.put(nums[i], map.get(nums[i]) + 1);
            else
                map.put(nums[i], 1);
        }
        // 优先队列 中 存放的是
        PriorityQueue<Freq> queue = new PriorityQueue<>();

        for (int key : map.keySet()) {
            if (queue.size() < k) {
                queue.add(new Freq(key, map.get(key)));
            } else if (map.get(key) > queue.peek().freq) {
                queue.remove();
                queue.add(new Freq(key, map.get(key)));
            }
        }
        int[] res = new int[queue.size()];
        for (int i = 0; i < res.length; i++) {
            res[i] = queue.remove().value;
        }
        return res;
    }
    public static void main(String[] args) {
        int[] test = {1,1,1,2,2,3};
        int[] ret = topKFrequent(test, 2);
        for (int i :ret)
            System.out.print(i + ",");
    }
}
方法二:直接在优先队列的构造函数中传入 比较规则,因为内部类可以访问 方法的final变量(map),并获取到map的 value
package com.study.MaxHeap.TopKFrequentElements347;
Solution {
    //升级版本  取消了自定义的内部类 进行 比较大小
    //直接在 PriorityQueue的构造函数中 传入 Comparator 写明 比较规则
    public static int[] topKFrequent(int[] nums, int k) {
        final TreeMap<Integer, Integer> map = new TreeMap<>();  //jdk1.8后final 可以不写 ,但需要 名义final,即 后面不可改变
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(nums[i]))
                map.put(nums[i], map.get(nums[i]) + 1);
            else
                map.put(nums[i], 1);
        }
        //因为 匿名内部类 可以直接获取到 方法中的 final变量(map) 所以可以直接在优先队列PriorityQueue存放 key,但是比较map的value
        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer a, Integer b) {
                return map.get(a) - map.get(b);
            }
        });
        for (int key : map.keySet()) {
            if (queue.size() < k) {
                queue.add(key);
            } else if (map.get(key) > map.get(queue.peek())) {
                queue.remove();
                queue.add(key);
            }
        }
        int[] res = new int[queue.size()];
        for (int i = 0; i < res.length; i++) {
            res[i] = queue.remove();
        }
        return res;
    }
    public static void main(String[] args) {
        int[] test = {1,1,1,2,2,3};
        int[] ret = topKFrequent(test, 2);
        for (int i :ret)
            System.out.print(i + ",");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值