347. 前 K 个高频元素

余生颓废 提交于 2020-01-31 04:14:27

方法很好想,要么暴力排序,归并,堆排都能满足O(nlogn)的要求。

我第一次想到的就是,用哈希统计一下数字,然后重载排一下序,顺序放入集合里就行。

这次用的是最小堆,主要学习一下PriorityQueue,是基于优先级堆的无界优先级queue

Modifier and Type Method and Description
boolean add(E e) 将指定的元素插入到此优先级队列中。
void clear() 从此优先级队列中删除所有元素。
Comparator comparator() 返回用于为了在这个队列中的元素,或比较null如果此队列根据所述排序natural ordering的元素。
boolean contains(Object o) 如果此队列包含指定的元素,则返回 true
Iterator iterator() 返回此队列中的元素的迭代器。
boolean offer(E e) 将指定的元素插入到此优先级队列中。
E peek() 检索但不删除此队列的头,如果此队列为空,则返回 null
E poll() 检索并删除此队列的头,如果此队列为空,则返回 null
boolean remove(Object o) 从该队列中删除指定元素的单个实例(如果存在)。
int size() 返回此集合中的元素数。
Object[] toArray() 返回一个包含此队列中所有元素的数组。
T[] toArray(T[] a) 返回一个包含此队列中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。
public class Main {
	public static void main(String[] args) {
		int n = 5;
		Solution solution = new Solution();
		System.out.println(solution.topKFrequent(new int[]{1,1,1,2,2,3}, 2));
	}
	
}
class Solution {
    public List<Integer> topKFrequent(int[] nums, int k) {
        HashMap<Integer, Integer> hs = new HashMap<Integer, Integer>();
        //统计每一个数出现的次数
        for (int num : nums) {
			if(hs.containsKey(num)) {
				hs.put(num, hs.get(num)+1);
			}else {
				hs.put(num, 1);
			}
		}
        //因为返回顺序没有要求,可以维护一个最小堆
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>(
        		new Comparator<Integer>() {
        			//重写比较方法,按照哈希的value大小排序
					@Override
					public int compare(Integer o1, Integer o2) {
						return hs.get(o1) - hs.get(o2);
					}
        		});
        for (Integer key : hs.keySet()) {
            if (pq.size() < k) {	//维护堆的大小为k
                pq.add(key);
            } else if (hs.get(key) > hs.get(pq.peek())) {//如果当前堆的大小超过k,并且当前遍历到的value值大于堆中最小的value值
                pq.remove();
                pq.add(key);
            }
        }
        List<Integer> list = new LinkedList<Integer>();
        while (!pq.isEmpty()) {
        	//System.out.println(pq.peek());
        	list.add(pq.remove());	//remove返回
        }
        return list;
    }
}s

以1,1,1,2,2,3为例。

有三个键值对<1,3>,<2,1>, < 3,1>,最终优先队列从队首到队尾的元素为:2,1

按照value大小排序,2的value较小,所以排在前面(维护的是最小堆)。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!