zoukankan      html  css  js  c++  java
  • leetcode347

    Given a non-empty array of integers, return the k most frequent elements.
    Example 1:
    Input: nums = [1,1,1,2,2,3], k = 2
    Output: [1,2]
    Example 2:
    Input: nums = [1], k = 1
    Output: [1]
    Note:
    * You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
    * Your algorithm's time complexity must be better than O(n log n), where n is the array's size.

    共用部分是用map统计频次。接下来选出topk频次有variation。

    1.O(nlogk), O(k). 堆。
    写专属comparator,根据Entry<K, V>里的V也就是本题的频率排序,让堆顶始终维持是最小频率的元素,你最菜,当堆大小过k的时候把你挤走哦!

    2.O(n), O(n). bucket sort。要用到频率最多也就是n的信息+O(n)的空间。
    第一遍扫计算频率
    第二遍扫根据频率把元素值放到对应frequency的bucket里。
    第三遍扫bucket,从右往左(从高频到低频),凑满k个元素。
    细节:
    1.bucket因为不能保证某一频率只有一元素,所以要用List<Integer>[], generic type初始化特别,要List<Integer>[] buckets = new List[nums.length + 1];注意等号右边不带generic 

    实现1:

    class Solution {
        private class EntryComparator implements Comparator<Map.Entry<Integer, Integer>> {
            @Override
            // P2: 要过OJ要声明一下Map.Entry, 没办法只写Entry,因为不够普遍吧,没适配。
            public int compare(Map.Entry<Integer, Integer> a, Map.Entry<Integer, Integer> b) {
                return a.getValue() - b.getValue();
            }
        }
        
        public List<Integer> topKFrequent(int[] nums, int k) {
            Map<Integer, Integer> freqs = new HashMap<>();
            for (int num : nums) {
                freqs.put(num, freqs.getOrDefault(num, 0) + 1);
            }
            
            // 1.PQ
            PriorityQueue<Map.Entry<Integer, Integer>> minHeap = new PriorityQueue<>(new EntryComparator());
            for (Map.Entry<Integer, Integer> e : freqs.entrySet()) {
                minHeap.offer(e);
                if (minHeap.size() > k) {
                    minHeap.poll();
                }
            }
            List<Integer> ans = new ArrayList<>();
            for (int i = 0; i < k; i++) {
                // P1:注意加到答案的是key不是entry
                ans.add(minHeap.poll().getKey());
            }
            Collections.reverse(ans);
            return ans;
        }
    }

    实现2:

    class Solution {
        public List<Integer> topKFrequent(int[] nums, int k) {
            Map<Integer, Integer> freqs = new HashMap<>();
            for (int num : nums) {
                freqs.put(num, freqs.getOrDefault(num, 0) + 1);
            }
            
            // 1.bucket sort
            // P1: 注意这个初始化!
            List<Integer>[] buckets = new List[nums.length + 1];
            for (int num : freqs.keySet()) {
                int frequency = freqs.get(num);
                if (buckets[frequency] == null) {
                    buckets[frequency] = new ArrayList<>();
                }
                buckets[frequency].add(num);
            }
            
            List<Integer> ans = new ArrayList<>();
            for (int i = buckets.length - 1; i >= 0; i--) {
                if (buckets[i] == null) {
                    continue;
                }
                for (int j = 0; j < buckets[i].size() && k > 0; j++) {
                    ans.add(buckets[i].get(j));
                    k--;
                }
            }
            return ans;
        }
    }
  • 相关阅读:
    Boliuraque OI 总结
    HNU 1447 最长上升路径
    妹纸
    某个子串的循环节
    跳石头
    小澳的葫芦
    递推式的循环问题
    BZOJ 2326 数学作业
    BZOJ 2337 XOR和路径
    hdu5468 Puzzled Elena
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/9739815.html
Copyright © 2011-2022 走看看