zoukankan      html  css  js  c++  java
  • 347. Top K Frequent Elements

    三刷。
    准备面试正好有这个题,把3种方式都撸一下试试。

    先是Bucket Sort。因为我们知道所有数据(frequency)的值域:最小是0,element在数组中一次都未出现;最大是数组长度,整个数组只含此element,有了值域就适合Bucket。

    前面按出现频率建map,记录每个int出现了多少次,然后按照出现次数入桶int[] bucket,最后倒着遍历,只要桶不是空的就把里面元素加到解里,K个解之后返还。

    Time: 建图O(n),入桶O(n),最后检查桶,也是O(n). 最后是O(n)

    Space: map O(n), bucket array O(n). 最后O(n)

    public class Solution {
        public List<Integer> topKFrequent(int[] nums, int k) {
            List<Integer> res = new ArrayList<>();
            if (k == 0 || nums.length == 0) return res;
            
            Map<Integer, Integer> map = new HashMap<>();
            for (int i : nums) {
                map.put(i, map.getOrDefault(i, 0) + 1);
            }
            
            List<Integer>[] bucket = new List[nums.length + 1];
            for (int i : map.keySet()) {
                int val = map.get(i);
                if (bucket[val] == null) {
                    bucket[val] = new ArrayList<Integer>();
                }
                bucket[val].add(i);
            }
            
            for (int i = bucket.length - 1; i >= 0; i--) {
                if (bucket[i] != null) {
                    res.addAll(bucket[i]);
                    k -= bucket[i].size();
                    if (k == 0) break;
                }
            }
            
            return res;
        }
    }
    

    方法二:
    Max Heap:

    首先还是建图,然后按照出现频率放到maxHeap里,然后取出TOP K个就行了,很直接。

    Time: 建图O(n) 入pq是 O(n*lgn) TOP K个是 O(klgn) O(n + (n+k)lgn)

    Space: 图O(n),PQ takes O(n)

    public class Solution {
        public List<Integer> topKFrequent(int[] nums, int k) {
            List<Integer> res = new ArrayList<>();
            if (k == 0 || nums.length == 0) return res;
            
            Map<Integer, Integer> map = new HashMap<>();
            for (int i : nums) {
                map.put(i, map.getOrDefault(i, 0) + 1);
            }
            
            PriorityQueue<Integer> pq = new PriorityQueue<Integer>(new Comparator<Integer>() {
               public int compare(Integer a, Integer b) {
                   return -Integer.compare(map.get(a), map.get(b));
               }
            });
            
            for (int i : map.keySet()) {
                pq.offer(i);
            }
            
            for (int i = 0; i < k ; i++) {
                res.add(pq.poll());
            }
            
            return res;
        }
    }
    

    方法三:
    MinHeap

    前面一样,是miniHeap,队列最前是出现频率最小的element,而且一旦队列size大于K,直接POLL顶端,因为最小的不可能是要求的元素。

    Time: 图 O(n), PQ入各种数字,然后保持K的大小应该是(n-k)lgK + KlgK(最后一个似乎可以省略,直接加PQ是可以的)

    O(n + (n-KlgK)

    public class Solution {
        public List<Integer> topKFrequent(int[] nums, int k) {
            List<Integer> res = new ArrayList<>();
            if (k == 0 || nums.length == 0) return res;
            
            Map<Integer, Integer> map = new HashMap<>();
            for (int i : nums) {
                map.put(i, map.getOrDefault(i, 0) + 1);
            }
            
            PriorityQueue<Integer> pq = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
               public int compare(Integer a, Integer b) {
                   return Integer.compare(map.get(a), map.get(b));
               } 
            });
            
            for (int i : map.keySet()) {
                pq.offer(i);
                if (pq.size() > k) {
                    pq.poll();
                }
            }
            
            res.addAll(pq);
            return res;
        }
    }
    
  • 相关阅读:
    webpack中文网的错误&&未更新内容(webpack4)
    本地运行别人的vue项目;新建一个vue项目;打包并部署一个vue项目
    ajax/JSON
    弹性盒模型,FLEX
    opencv-python-学习笔记五(图像的基本操作)
    opencv-python-学习笔记四(创建滑动条)
    opencv-python-学习笔记三(鼠标事件)
    opencv-python-学习笔记二(利用opencv绘图)
    opencv-python-学习笔记一(图像的读取与写入)
    开发Koa 必须用的插件
  • 原文地址:https://www.cnblogs.com/reboot329/p/6128334.html
Copyright © 2011-2022 走看看