[LeetCode]460. LFU Cache

来源:互联网 发布:阿里云备案承诺书demo 编辑:程序博客网 时间:2024/06/06 01:12

https://leetcode.com/problems/lfu-cache/#/description

实现一个 Least Frequently Used (LFU),保存访问频率最高的capacity个数,如果要淘汰的可能有多个数频率相同,则淘汰最后一次访问时间最靠前的

lintcode本题测试集不完整



用bucket链表,每个bucket内保存同一个count的所有元素,bucket内部用类似LRU来实现保存元素(head && tail),这样保证在O(1)时间内插入、删除特定元素或者进行淘汰

public class LFUCache {    int capacity;    DListBucket head;    DListBucket tail;    HashMap<Integer, Node> map;    HashMap<Integer, DListBucket> bucketMap;        class DListBucket {        int count;        Node nodeHead;        Node nodeTail;        DListBucket pre;        DListBucket next;        public DListBucket(int count) {            this.count = count;            nodeHead = new Node(0, 0, 0);            nodeTail = new Node(0, 0, 0);            nodeHead.next = nodeTail;            nodeTail.pre = nodeHead;        }    }        class Node {        int key;        int val;        int count;        Node pre;        Node next;        public Node(int key, int val, int count) {            this.key = key;            this.val = val;            this.count = count;        }    }    // @param capacity, an integer    public LFUCache(int capacity) {        // Write your code here        this.capacity = capacity;        head = new DListBucket(Integer.MIN_VALUE);        tail = new DListBucket(Integer.MIN_VALUE);        head.next = tail;        tail.pre = head;        map = new HashMap();        bucketMap = new HashMap();    }    // @param key, an integer    // @param value, an integer    // @return nothing    public void put(int key, int value) {        // Write your code here        if (capacity == 0) {            return;        }        if (map.containsKey(key)) {            Node node = map.get(key);            node.pre.next = node.next;            node.next.pre = node.pre;            DListBucket next = null;            if (bucketMap.get(node.count).next.count != node.count + 1) {                next = insertBucket(node.count + 1, bucketMap.get(node.count));            } else {                next = bucketMap.get(node.count).next;            }            node.count++;            node.val = value;            node.pre = next.nodeTail.pre;            node.next = next.nodeTail;            next.nodeTail.pre = node;            node.pre.next = node;        } else {            Node node = new Node(key, value, 1);            map.put(key, node);            DListBucket next = null;            if (head.next.count != 1) {                next = insertBucket(1, head);            } else {                next = head.next;            }            node.pre = next.nodeTail.pre;            node.next = next.nodeTail;            next.nodeTail.pre = node;            node.pre.next = node;            if (map.size() > capacity) {                removeLastNode(node);            }        }    }        private void removeLastNode(Node cur) {        Node nodeHead = head.next.nodeHead;        Node node = null;        if (nodeHead.next == cur && head.next.next.nodeHead.next != head.next.next.nodeTail) {            node = head.next.next.nodeHead.next;        } else {            node = head.next.nodeHead.next;        }        node.pre.next = node.next;        node.next.pre = node.pre;        map.remove(node.key);    }    public int get(int key) {        // Write your code here        if (!map.containsKey(key)) {            return -1;        }        Node node = map.get(key);        node.pre.next = node.next;        node.next.pre = node.pre;        DListBucket next = null;        if (bucketMap.get(node.count).next.count != node.count + 1) {            next = insertBucket(node.count + 1, bucketMap.get(node.count));        } else {            next = bucketMap.get(node.count).next;        }        node.count++;        node.pre = next.nodeTail.pre;        node.next = next.nodeTail;        next.nodeTail.pre = node;        node.pre.next = node;        return node.val;    }        private DListBucket insertBucket(int count, DListBucket pre) {        DListBucket bucket = new DListBucket(count);        bucket.next = pre.next;        bucket.pre = pre;        pre.next = bucket;        bucket.next.pre = bucket;        bucketMap.put(count, bucket);        return bucket;    }}


0 0
原创粉丝点击