1. 程式人生 > >LeetCode之347. 前K個高頻元素

LeetCode之347. 前K個高頻元素

參考知識:優先佇列      (通過最大堆實現的)

優先佇列的作用是能保證每次取出的元素都是佇列中權值最小的(Java的優先佇列每次取最小元素)。這裡牽涉到了大小關係,元素大小的評判可以通過元素本身的自然順序(natural ordering),也可以通過構造時傳入的比較器Comparator)。

Java中PriorityQueue實現了Queue介面,不允許放入null元素;其通過最小堆實現

 

 

題目描述:

給定一個非空的整數陣列,返回其中出現頻率前 高的元素。

示例 1:

輸入: nums = [1,1,1,2,2,3], k = 2
輸出: [1,2]

示例 2:

輸入: nums = [1], k = 1
輸出: [1]

說明:

  • 你可以假設給定的 總是合理的,且 1 ≤ k ≤ 陣列中不相同的元素的個數。
  • 你的演算法的時間複雜度必須優於 O(n log n) , 是陣列的大小

 

 解答:



import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;
import java.util.PriorityQueue;
 class Solution {
	public List<Integer> topKFrequent(int[] nums, int k) {
        
		TreeMap<Integer,Integer> map=new TreeMap<>();
		//將陣列中的值放入map集合中,並統計其出現頻次
		for(int num:nums){
			if(!map.containsKey(num)) {
				map.put(num,1);
			}
			map.put(num, map.get(num)+1);
		}
		
		//java中的優先佇列(小頂堆),傳入比較器
		PriorityQueue<Integer> queue=new PriorityQueue<>(new Comparator<Integer>() {

			@Override
			public int compare(Integer o1, Integer o2) {
				return map.get(o1)-map.get(o2);
			}
			
		});
		//迴圈遍歷map集合,將前K高的元素放入優先佇列中
		for(int key:map.keySet()) {
			if(queue.size()<k) {
				queue.add(key);
			}else if(map.get(key)>map.get(queue.peek())){
				queue.remove();
				queue.add(key);
			}
		}
		
		
		LinkedList<Integer> res=new LinkedList<>();
		//將優先佇列轉為list輸出
		while(!queue.isEmpty()) {
			res.add(queue.remove());
		}
		return res;
			
		
    }
}