手敲数据结构——基于最大堆实现优先队列

这里实现的优先队列是基于最大堆实现的,java系统是基于最小堆实现的。

队列接口

public interface Queue {

    int getSize();
    boolean isEmpty();
    void enqueue(E e);
    E dequeue();
    E getFront();
}

优先队列实现

public class PriorityQueue> implements Queue{

    private MaxHeap queue;

    public PriorityQueue() {
        queue = new MaxHeap<>();
    }

    @Override
    public int getSize() {
        return queue.size();
    }

    @Override
    public boolean isEmpty() {
        return queue.isEmpty();
    }

    @Override
    public void enqueue(E e) {
        queue.add(e);
    }

    @Override
    public E dequeue() {
        return queue.extractMax();
    }

    @Override
    public E getFront() {
        return queue.findMax();
    }
}

LeetCode上的问题

347. 前K个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
例如,
给定数组 [1,1,1,2,2,3] , 和 k = 2,返回 [1,2]。
注意:
你可以假设给定的 k 总是合理的,1 ≤ k ≤ 数组中不相同的元素的个数。
你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。

public class Solution {

    private class Freq implements Comparable {
        int e;
        int freq;

        public Freq(int e, int freq) {
            this.e = e;
            this.freq = freq;
        }

        @Override
        public int compareTo(Freq o) {
            return o.freq - freq;
        }
    }

    public List topKFrequent(int[] nums, int k) {
        TreeMap treeMap = new TreeMap<>();
        for (int num : nums) {
            if (treeMap.containsKey(num))
                treeMap.put(num, treeMap.get(num) + 1);
            else
                treeMap.put(num, 1);
        }
        PriorityQueue queue = new PriorityQueue<>();
        for (int key : treeMap.keySet()) {
            if (queue.getSize()< k)
                queue.enqueue(new Freq(key,treeMap.get(key)));
            else if (treeMap.get(key) > queue.getFront().freq) {
                queue.dequeue();
                queue.enqueue(new Freq(key,treeMap.get(key)));
            }
        }
        LinkedList res = new LinkedList<>();
        while (!queue.isEmpty())
            res.add(queue.dequeue().e);
        return res;
    }

}

使用系统的优先队列实现

import java.util.*;
import java.util.PriorityQueue;

public class Solution1 {

    public List topKFrequent(int[] nums, int k) {
        TreeMap treeMap = new TreeMap<>();
        for (int num : nums) {
            if (treeMap.containsKey(num))
                treeMap.put(num, treeMap.get(num) + 1);
            else
                treeMap.put(num, 1);
        }
        PriorityQueue queue = new PriorityQueue<>(Comparator.comparingInt(treeMap::get));
        for (int key : treeMap.keySet()) {
            if (queue.size()< k)
                queue.add(key);
            else if (treeMap.get(key) > treeMap.get(queue.peek())) {
                queue.remove();
                queue.add(key);
            }
        }
        LinkedList res = new LinkedList<>();
        while (!queue.isEmpty())
            res.add(queue.remove());
        return res;
    }

}

你可能感兴趣的:(手敲数据结构——基于最大堆实现优先队列)