Top K问题

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

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

方法一:堆排序

思路:先用一个HashMap存储每个数字及其对应的出现次数,并建立一个PriorityQueue用于存储元素并进行排序,之后遍历整个HashMap,当PriorityQueue中元素不满k个的时候直接将元素与其出现次数加入PriorityQueue,当其中元素已有k个且当前元素出现次数大于PriorityQueue中最小的出现次数的时候从PriorityQueue中取出出现次数最少的元素(因为PriorityQueue已被排序,故直接执行poll操作即可),并将当前元素及其出现次数加入PriorityQueue,遍历完成后出现次数前k大的元素已被存储在PriorityQueue中,之后利用PriorityQueue创建答案数组即可。

public int[] topKFrequent(int[] nums, int k) {
        HashMap<Integer,Integer> map=new HashMap();
        int[] ans=new int[k];
        for(int i=0;i<nums.length;i++)
        {
            map.put(nums[i],map.getOrDefault(nums[i],0)+1);
        }
        PriorityQueue<int[]>que=new PriorityQueue(new Comparator<int[]>(){
            public int compare(int m[],int n[]){
                return m[1]-n[1];
            }
        });

        for(Map.Entry<Integer,Integer> entry:map.entrySet()){
            if(que.size()==k){
                if(entry.getValue()>que.peek()[1])
                {
                    que.poll();
                    que.offer(new int[]{entry.getKey(),entry.getValue()});
                }
            }else{
                que.offer(new int[]{entry.getKey(),entry.getValue()});
            }
        }

        for(int i=0;i<k;++i){
            ans[i]=que.poll()[0];
        }

        return ans;
    }

方法二:桶排序

新建hashmap的同时可以得到最大出现次数maxtimes,我们新建一个长度为maxtimes+1的arraylist数组buckets,buckets[i[用于存储出现次数为i的元素,随后从后先前遍历buckets,依次将其中元素加入ans数组,当加入元素数母等于k时结束遍历,此时前k大的元素已被加入数组。

public int[] topKFrequent(int[] nums, int k) {
        HashMap<Integer,Integer> map=new HashMap();
        int[] ans=new int[k];
        int index=0;
        int maxtimes=0;
        for(int i=0;i<nums.length;i++)
        {
            map.put(nums[i],map.getOrDefault(nums[i],0)+1);
            maxtimes=Math.max(maxtimes,map.get(nums[i]));
        }
        ArrayList<Integer>[] buckets=new ArrayList[maxtimes+1];
        for(int i=0;i<maxtimes+1;i++)
           buckets[i]=new ArrayList();
        map.forEach((k,v)->{
        });
        map.forEach((num, freq) -> {
            buckets[freq].add(num);
        });
        for(int i=maxtimes;i>=1&&index<k;i--){
            for(int j:buckets[i]){
                ans[index++]=j;
                if(index==k)
                   break;
            }
        }
        return ans;
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 什么是 Top K 问题?简单来说就是在一堆数据里面找到前 K 大(当然也可以是前 K 小)的数。这个问题也是十分...
    Howie_Y阅读 52,033评论 1 39
  • 问题:海量数据处理 - 10亿个数中找出最大的10000个数。解决方案:先拿10000个数建堆,然后一次添加剩余元...
    woshishui1243阅读 5,092评论 1 1
  • 先拿10000个数建堆,然后依次添加剩余元素,如果大于堆顶的数(10000中最小的),将这个数替换堆顶,并调整结构...
    金星show阅读 844评论 0 1
  • 前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去...
    左上偏右阅读 6,937评论 0 11
  • 快速排序,堆排序和 问题一直都是非常经典的算法知识点。并且他们在原理和算法思想上有相通的部分。这篇文章会简要复习...
    dyume阅读 991评论 1 0