LeetCode32|前k个高频元素

时间:2022-07-23
本文章向大家介绍LeetCode32|前k个高频元素,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1,问题简述

给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

2,示例

示例 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 个高频元素的集合是唯一的。
你可以按任意顺序返回答案。

3,题解思路

键值对集合使用。

4,题解程序

 
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class TopKFrequentTest {
    public static void main(String[] args) {
        int[] nums = {1, 1, 1, 2, 2, 3};
        int k = 2;
        int[] topKFrequent = topKFrequent(nums, k);
        for (Integer num : topKFrequent) {
            System.out.print(num + "t");
        }
        System.out.println();
        int[] topKFrequent2 = topKFrequent2(nums, k);
        for (Integer num : topKFrequent2) {
            System.out.print(num + "t");
        }
    }


    public static int[] topKFrequent2(int[] nums, int k) {
        if (nums == null || nums.length == 0 || nums.length < k) {
            return new int[0];
        }
        PriorityQueue<Map.Entry<Integer, Integer>> priorityQueue = new PriorityQueue<>((x, y) -> {
            Integer xValue = x.getValue();
            Integer yValue = y.getValue();
            return yValue.compareTo(xValue);
        });
        HashMap<Integer, Integer> hashMap = new HashMap<>(nums.length);
        for (Integer num : nums) {
            if (hashMap.containsKey(num)) {
                hashMap.put(num, hashMap.get(num) + 1);
            } else {
                hashMap.put(num, 1);
            }
        }
        List<Map.Entry<Integer, Integer>> entryList = new ArrayList<>(hashMap.entrySet());
        entryList.forEach(priorityQueue::offer);
        return IntStream.range(0, k).map(i -> Objects.requireNonNull(priorityQueue.poll()).getKey()).toArray();
    }

    public static int[] topKFrequent(int[] nums, int k) {
        if (nums == null || nums.length == 0 || nums.length < k) {
            return new int[0];
        }
        HashMap<Integer, Integer> map = new HashMap<>(nums.length);
        for (Integer num : nums) {
            if (map.containsKey(num)) {
                map.put(num, map.get(num) + 1);
            } else {
                map.put(num, 1);
            }
        }
        List<Map.Entry<Integer, Integer>> entryList = map.entrySet().stream().sorted((o1, o2) -> o2.getValue().compareTo(o1.getValue())).collect(Collectors.toList());
        return IntStream.range(0, k).map(i -> entryList.get(i).getKey()).toArray();
    }
}

5,题解程序图片版

6,键值对集合的使用,这里自己也曾经分析过java集合的源码,具体见下面的链接吧,但是自己从未去写过hashMap的源码,因为网络上这样的文章的太多了,自己倒是分析过HashSet的源码java进阶|HashSet的源码分析,HashSet是基于HashMap的基础上实现的,自己也分过HashMap的源码文章,但是从没有去写一篇文章