Top K Frequent Elements Leetcode

Given a non-empty array of integers, return the k most frequent elements.

For example,
Given [1,1,1,2,2,3] and k = 2, return [1,2].

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.
 
这道题用hashmap和priorityqueue很快就通过了。需要注意的是priorityqueue默认是最小堆,所以写comparator的时候要注意反过来写。
感觉自己最近的代码还挺优雅的,而且除了忘记了最小堆还有一个右括号一遍就过了,有进步哈哈哈。
public class Solution {
    public List<Integer> topKFrequent(int[] nums, int k) {
        List<Integer> res = new ArrayList<>();
        if (nums == null || nums.length == 0) {
            return res;
        }
        Map<Integer, Integer> hm = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            hm.put(nums[i], hm.getOrDefault(nums[i], 0) + 1);
        }
        
        PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>(){
            public int compare(Integer n1, Integer n2) {
                return hm.get(n2) - hm.get(n1);
            }
        });
        for (Integer n : hm.keySet()) {
            pq.add(n);
        }
        for (int i = 0; i < k; i++) {
            res.add(pq.poll());
        }
        return res;
    }
}

不过高兴了半天发现时间复杂度是O(nlogn)着实伤心。。。还是要用bucket sort来实现比较好。学习了。

bucket sort, 桶排序就是先把数组按一定的规则排到bucket里面,此题是按照频率来排序,然后从后往前输出。

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

这个时间复杂度是O(n)了。介于最后一个桶的个数可能大于k,所以最好的是返回个数为k的sublist。

posted @ 2017-02-15 04:02  璨璨要好好学习  阅读(156)  评论(0编辑  收藏  举报