1. 程式人生 > >LeetCode347:返回頻率前K高的元素,基於優先隊列實現

LeetCode347:返回頻率前K高的元素,基於優先隊列實現

The link leet 存儲 pac err style 映射 structure

package com.lt.datastructure.MaxHeap;

import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;

import com.lt.datastructure.Queue.PriorityQueue;
/**
LeetCode347
 給定一個非空的整數數組,返回其中出現頻率前 k 高的元素。
示例 1:
輸入: nums = [1,1,1,2,2,3], k = 2
輸出: [1,2]
說明:
    你可以假設給定的 k 總是合理的,且 1 ≤ k ≤ 數組中不相同的元素的個數。
    你的算法的時間復雜度必須優於 O(n log n) , n 是數組的大小。
    
  頻次: 用map    復雜度優於O(nlogn):優先隊列  頻次越低,優先於越高
  1 TreeMap存儲,鍵存數組的值,值存數組的值頻次
  2 新建Freq類,成員屬性是e,freq,實現Comparable,重寫CompareTo,相反地,頻次小的優先級高,返回1
  3 優先隊列存儲Freq,遍歷map,如果沒存滿k個,繼續入隊,如果存滿了,將隊首元素和新元素的頻次比較,優先級高的(頻次低)出隊
  4 用LinkedList存儲優先隊列中的元素,作為結果輸出
*/ public class Solution{ private class Freq implements Comparable<Freq>{ public int e,freq; public Freq(int e, int freq) { this.e = e; this.freq = freq; } @Override public int compareTo(Freq another) { if(this.freq < another.freq){
return 1; }else if(this.freq > another.freq){ return -1; }else{ return 0; } } } public List<Integer> topKFrequent(int[] nums, int k) { //映射存儲元素和頻次 TreeMap<Integer,Integer> map = new
TreeMap<>(); for(int num : nums){ if(map.containsKey(num)){ map.put(num, map.get(num)+1); }else{ map.put(num, 1); } } //優先隊列存儲前k個頻次最高的元素 PriorityQueue<Freq> pq = new PriorityQueue<>(); for(int key : map.keySet()){ //沒存滿,繼續存 if(pq.getSize()<k){ pq.enqueue(new Freq(key,map.get(key))); //存滿了,比較次數,次數低的優先級高,出隊,頻次高的入隊 }else if(map.get(key)>pq.getFront().freq){ pq.dequeue(); pq.enqueue(new Freq(key,map.get(key))); } } //將優先隊列的元素存於鏈表並作為結果輸出 LinkedList<Integer> res = new LinkedList<>(); while(!pq.isEmpty()){ res.add(pq.dequeue().e); } return res; } }

LeetCode347:返回頻率前K高的元素,基於優先隊列實現