LeetCode Everyday: 347. Top K Frequent Elements

本文介绍了一种高效算法来找出数组中出现频率最高的 k 个元素,并提供了两种方法实现,一种是计数排序法,另一种是利用优先队列实现的方法。这两种方法都优于传统的 n log n 时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

</pre>https://leetcode.com/problems/top-k-frequent-elements/Given a non-empty array of integers, return the <span style="box-sizing: border-box; font-weight: 700;"><span style="box-sizing: border-box;">k</span></span> most frequent elements.</p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 10px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 30px;">For example,<br style="box-sizing: border-box;" />Given <code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12.6px; padding: 2px 4px; color: rgb(199, 37, 78); border-radius: 4px; background-color: rgb(249, 242, 244);">[1,1,1,2,2,3]</code> and k = 2, return <code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12.6px; padding: 2px 4px; color: rgb(199, 37, 78); border-radius: 4px; background-color: rgb(249, 242, 244);">[1,2]</code>.</p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 10px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 30px;"><span style="box-sizing: border-box; font-weight: 700;">Note: </span><br style="box-sizing: border-box;" /></p><ul style="box-sizing: border-box; margin-top: 0px; margin-bottom: 10px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 30px;"><li style="box-sizing: border-box;">You may assume <span style="box-sizing: border-box;">k</span> is always valid, 1 ≤ <span style="box-sizing: border-box;">k</span> ≤ number of unique elements.</li></ul><p></p><ul style="box-sizing: border-box; margin-top: 0px; margin-bottom: 10px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 30px;"><li style="box-sizing: border-box;">Your algorithm's time complexity <span style="box-sizing: border-box; font-weight: 700;">must be</span> better than O(<span style="box-sizing: border-box;">n</span> log <span style="box-sizing: border-box;">n</span>), where <span style="box-sizing: border-box;">n</span> is the array's size.</li></ul><div><span style="font-family:Helvetica Neue, Helvetica, Arial, sans-serif;color:#333333;"><span style="font-size: 14px; line-height: 30px;">Method 1: count sort. O(n)</span></span></div><div><span style="font-family:Helvetica Neue, Helvetica, Arial, sans-serif;color:#333333;"><span style="font-size: 14px; line-height: 30px;"></span></span><pre name="code" class="java">public class Solution {
    public List<Integer> topKFrequent(int[] nums, int k) {
        HashMap<Integer,Integer> hm = new HashMap<Integer,Integer>();
        int max = 0;
        for(int i:nums){
            int n = hm.getOrDefault(i,0)+1;
            max = Math.max(max,n);
            hm.put(i,n);
        }
        ArrayList<Integer>[] arr = new ArrayList[max+1];
        for(int i=0;i<arr.length; i++){
            arr[i] = new ArrayList<Integer>();
        }
        ArrayList<Integer> ret = new ArrayList<Integer>();
        for(int i: hm.keySet()){
            arr[hm.get(i)].add(i);
        }
        int add = k;
        while(k>0){
            ret.addAll(arr[max]);
            k-=arr[max].size();
            max--;
        }
        return ret;
    }
}

Method 2: 

Idea is very straightforward:

  • build a counter map that maps a num to its frequency
  • build a heap/priority queue that keeps track of k most significant entries
  • iterate through the final heap and get the keys
  • The total time complexity I think should be O(N+k+(N-k)lgk), where N is the time spent on traversing over the map, k is the time to build heap, and (N-k)lgk is the time to insert the remaining (N-k)elements.

Code in Java:


public List<Integer> topKFrequent(int[] nums, int k) {
    Map<Integer, Integer> counterMap = new HashMap<>();
    for(int num : nums) {
        int count = counterMap.getOrDefault(num, 0);
        counterMap.put(num, count+1);
    }

    PriorityQueue<Map.Entry<Integer, Integer>> pq = new PriorityQueue<>((a, b) -> a.getValue()-b.getValue());
    for(Map.Entry<Integer, Integer> entry : counterMap.entrySet()) {
        pq.offer(entry);
        if(pq.size() > k) pq.poll();
    }

    List<Integer> res = new LinkedList<>();
    while(!pq.isEmpty()) {
        res.add(0, pq.poll().getKey());
    }
    return res;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值