460. LFU缓存

题目地址:https://leetcode-cn.com/problems/lfu-cache/submissions/

代码地址:https://github.com/javartisan/edx-ds/blob/master/src/main/java/com/javartisan/leetcode/LFUCache460.java

class LFUCache {

    private static class Node{
        public int key=-1;
        public int value=-1;
        public Node next;
        public Node lNext;
        public Node lBefore;
        public int count=1; 
    }

    private int capacity;
    private int size;
    private int tabSize=15;

    private Node hashTab[];

    private Node head;
    private Node tail;

    public LFUCache(int capacity) {
        
        this.capacity =capacity;
        // 参见HashMap实现,必须+1,不然7的话,如果key=7则会数组越界
        hashTab =new Node[tabSize+1];
        head =new Node();
        tail = new Node();
        head.lNext=tail;
        tail.lBefore=head;
    }
    
    public int get(int key) {

        int hash =hash(key);
        Node node =hashTab[hash];
        while(node!=null){
            if(node.key==key){
                node.count=node.count+1;
                Node nodeNext =node.lNext;
                connect(node.lBefore,node.lNext);
                update(node,nodeNext);
                return node.value;
            }
            node=node.next;
        }
        return -1;
        
    }
    
    public void put(int key, int value) {
        if(capacity==0){
            return;
        }
        ensureCapacity(key);

        int hash = hash(key);
        Node node = hashTab[hash];
        if(node!=null){
            if(node.key==key){
                   node.value =value;
                   node.count=node.count+1; 
                   connect(node.lBefore,node.lNext);
                   update(node,tail);

            }else{
                Node last=node;
                node =node.next;
                while(node!=null){
                    if(node.key==key){
                        node.value=value;
                        node.count=node.count+1;
                        connect(node.lBefore,node.lNext);
                           update(node,tail);
                        break;
                    }
                    last = node;
                    node=node.next;
                }
                if(node==null){
                    node = new Node();
                    node.key=key;
                    node.value=value;
                    last.next =node;
                    size++;
                    update(node,tail);
                }
            }
        }else{
            node = new Node();
            node.key=key;
            node.value=value;
            size++;
            hashTab[hash]=node;
            update(node,tail);
        }
    }
  


    public void update(Node node,Node currentNode){

        Node before = currentNode.lBefore;
        while(before!=null&&before!=head){
            if(before.count>node.count){
                break;
            }
            before=before.lBefore;
        }
        insert(node,before,before.lNext);
    }


    public boolean containKey(int key){
        int hash=hash(key);
        Node node =hashTab[hash];
        while(node!=null){
            if(node.key==key){
                return true;
            }
            node =node.next;
        }

        return false;
    }

    public void ensureCapacity(int key){

        if(size<capacity||(size==capacity&&containKey(key))){
            return ;
        }
        size--;
        Node delNode=tail.lBefore;
        Node before=delNode.lBefore;
        connect(before,tail);
        int hash=hash(delNode.key);
        Node node = hashTab[hash];
        if(node.key==delNode.key){
            hashTab[hash]=node.next;
            return;
        }
        Node last=node;
        node =node.next;
        while(node!=null){
            if(node.key==delNode.key){
                last.next=node.next;
            }
            last=node;
            node=node.next;
        }
    }


    public int hash(int key){
        // 使用2的N次方-1计算效率高,使用&分布更均匀
        return Math.abs(key)&tabSize;
    }

    public void connect(Node before,Node after){
        before.lNext = after;
        after.lBefore = before;
    }

    public void insert(Node insert,Node before,Node after){
            insert.lNext=after;
            insert.lBefore=before;
            before.lNext=insert;
            after.lBefore=insert;
    }


    public static void main(String[] args){
        LFUCache cache = new LFUCache(2);
        cache.put(1,1);
        cache.put(2,2);
        cache.put(3,3);
        System.out.println(cache.get(1));
        System.out.println(cache.get(2));
        System.out.println(cache.get(3));
        

    }

}

/**
 * Your LFUCache object will be instantiated and called as such:
 * LFUCache obj = new LFUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

猜你喜欢

转载自www.cnblogs.com/leodaxin/p/11329927.html