[高频面试题]获取N个元素中的前K个高频元素四种解决方法--双层循环、最大堆、最小堆、桶排序

获取N个元素中的前K个高频元素

题目描述:

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

示例1:

输入:nums=[1,1,1,2,2,3],k=2

输出:[1,2]

示例2:

输入:nums=[1],k=1

输出:[1]

说明:

1.你可以假设给定的K总是合理的,且1<=k<=数组中不相同的元素个数

2.你的算法时间复杂度必须优于O(nlogn),n是数组的大小。

题目思路:

1.遍历元素集,将具体的key值与其出现频率保存Map中;

2.使用优先级队列(最大堆)存储出现频率最高的前k个键值对;

3.使用List存储优先队列中的所有key

实现方法:

双层循环

最大堆

最小堆

桶排序

1.双层循环(时间复杂度不满足题目要求,但也可以实现)
package heapTask;

import java.util.*;

/**
 * 双层循环实现
 * 时间复杂度:O(nlogn),其中n表示数组长度
 * 空间复杂度:O(n),最极端情况下(每个元素都不同),用于存储元素及其频率的Map需要存储n个键值对
 */
public class Solution2 {
   
    public List<Integer> topKFrequent(Integer[] nums,int k){
   
        //第一步:统计元素频率存入map中
        Map<Integer,Integer> map=new HashMap<>();
        for(int i:nums){
   
            //若当前元素频率为空,说明当前元素为第一次出现,故频率设置为1
            if(map.get(i)==null)
                map.put(i,1);
            else{
   
                //若当前元素非第一次出现,则出现频率在之前的基础上加1
                map.put(i,map.get(i)+1);
            }
        }
        //对元素按照频率进行降序排序
        List<Map.Entry<Integer,Integer>> list=new ArrayList<>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
   
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
   
                return o2.getValue()-o1.getValue();
            }
        });
        //取出前K个元素
        int count=0;
        List<Integer> list1=new ArrayList<>();
        for(Map.Entry<Integer,Integer> entry:list){
   
            list1.add(entry.getKey());
            ++count;
            if(count>=k)
                break;
        }
        return list1;
    }
    public static void main(String[] args) {
   
        Integer[] nums=new Integer[]{
   1,1,1,2,2,3};
        List<Integer> list=new Solution2().topKFrequent(nums,2);
        System.out.println(list);
    }
}
//[1,2]
最大堆—自定义优先级队列

因优先级队列是基于堆实现的,故需首先创建最大堆实现基本功能(增加元素、取出元素等),之后自定义优先级队列依赖堆实现基本功能(入队、出队、堆顶元素、是否为空、堆中元素个数),最后根据该题三步解题思路做出该题。

//Heap.java
package heap;

import java.util.Arrays;
import java.util.Comparator;

//基于数组实现的二叉堆
public class Heap<E> {
   
    //实现任意类的大小比较
    private Comparator<E> comparator;
    private int size;
    private E[] elementData;
    //默认初始容量
    private static final int DEFAULT_CAPACITY=10;

    public Heap() {
   
        this(null,DEFAULT_CAPACITY);
    }

    public Heap(int initialCapacity) {
   
        this(null,initialCapacity);
    }

    public Heap(Comparator<E> comparator, int initialCapacity) {
   
        this.elementData= (E[]) new Object[initialCapacity];
        this.comparator=comparator;
    }
    public Heap(E[] arr){
   
        elementData= 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值