LeetCode347:返回频率前K高的元素

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;        
      }
  }

 

 

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


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) {
            
            Map<Integer, Integer> map = new TreeMap<>();
            for (int i : nums) {
                if(map.containsKey(i)){
                    map.put(i, map.get(i) + 1);
                }else{
                    map.put(i, 0);
                }
            }
            
            //最小堆,频次最高的优先出队
            PriorityQueue<Freq> queue = new PriorityQueue<>();
            for(int key : map.keySet()){
                if(queue.size() < k){
                    queue.add(new Freq(key, map.get(key)));
                }
                else if(map.get(key) > queue.peek().freq){
                    queue.remove();
                    queue.add(new Freq(key, map.get(key)));
                }
            }
            
            LinkedList<Integer> res = new LinkedList<>();
            while(!queue.isEmpty()){
                res.add(queue.remove().e);
            }
            return res;
     }
}

 

posted @ 2018-12-04 23:20  IslandZzzz  阅读(567)  评论(0编辑  收藏  举报