题解 | #设计LFU缓存结构#

设计LFU缓存结构

http://www.nowcoder.com/practice/93aacb4a887b46d897b00823f30bfea1

import java.util.*;


public class Solution {
    /**
     * lfu design
     * @param operators int整型二维数组 ops
     * @param k int整型 the k
     * @return int整型一维数组
     */
    public int[] LFU (int[][] operators, int k) {
        // write code here
        int count = 0;
        for(int[] opera : operators){
            if(opera[0] == 2){
                count++;
            }
        }
        int[] res = new int[count];
        LFUCache lfu = new LFUCache(k);
        int index = 0;
        for(int[] opera : operators){
            if(opera[0] == 1){
                lfu.set(opera[1],opera[2]);
            }else{
                int val = lfu.get(opera[1]);
                res[index++] = val;
            }
        }
        return res;
    }
}

class LFUCache{
    class Node{
        int val;
        int key;
        int freq = 1;
        Node next;
        Node pre;
        public Node(){};
        public Node(int key,int val){
            this.val = val;
            this.key = key;
        }
    }
    
    class DoubleLinkedList{
        Node head;
        Node tail;
        DoubleLinkedList(){
            head = new Node();
            tail = new Node();
            head.next = tail;
            tail.pre = head;
        }
        public void addNode(Node node){
            node.next = head.next;
            head.next.pre = node;
            node.pre = head;
            head.next = node;
        }
        
        public void removeNode(Node node){
            node.next.pre = node.pre;
            node.pre.next = node.next;
        }
    }
    
    
    
    
    Map<Integer,Node> cache;
    Map<Integer,DoubleLinkedList> freqMap;
    int min;
    int capacity;
    public LFUCache(int capacity){
        cache = new HashMap<>(capacity);
        freqMap = new HashMap<>();
        this.capacity = capacity;
    }
    
    public int get(int key){
        if(!cache.containsKey(key)){
            return -1;
        }
        Node node = cache.get(key);
        freqInc(node);
        return node.val;
    }
    public void set(int key,int val){
        if(!cache.containsKey(key)){
            if(cache.size() == capacity){
                DoubleLinkedList list = freqMap.get(min);
                cache.remove(list.tail.pre.key);
                list.removeNode(list.tail.pre);
            }
            Node newNode = new Node(key,val);
            cache.put(key,newNode);
            DoubleLinkedList newList = freqMap.get(1);
            if(newList == null){
                newList = new DoubleLinkedList();
                freqMap.put(1,newList);
            }
            newList.addNode(newNode);
            min = 1;
        }else{
            Node node = cache.get(key);
            node.val = val;
            freqInc(node);
        }
    }
    public void freqInc(Node node){
        int freq = node.freq;
        DoubleLinkedList list = freqMap.get(freq);
        list.removeNode(node);
        if(freq == min && list.head.next == list.tail){
            min = freq + 1;
        }
        node.freq++;
        DoubleLinkedList newList = freqMap.get(node.freq);
        if(newList == null){
            newList = new DoubleLinkedList();
            freqMap.put(node.freq,newList);
        }
        newList.addNode(node);
    }
}
全部评论

相关推荐

买蜜雪也用卷:我觉得应该没有哪个人敢说自己熟练使用git,代码分支一复杂还是得慢慢寻思一下的,不过基本的拉代码提交代码还有分支什么的是应该会
点赞 评论 收藏
分享
05-29 20:34
门头沟学院 C++
KarlAllen_直通春招版:得做好直接春招的准备。学历差的话,一是面试要求会比学历好的严格不少,二是就算面试通过了也会被排序。总之暑期和秋招对于学历差的就是及其不友好
点赞 评论 收藏
分享
学java时间比较短不到三个月,基本的技术栈都过了一遍就是都不太深,有个小项目。是继续找实习还是沉淀准备秋招呢?找实习的话会花很多时间在八股,放弃的话又怕秋招简历太难看。有无大佬支招
今天java了吗:1.一定要找实习,实习不一定要去,但是找实习过程中的面试经验和心态经验才是最重要的 2.八股本来就是大头,甚至比项目重要 3.这个时间段也是面试比较多的阶段,可以抓住机会锻炼。面试才会发现自己的不足,感觉自己会了和能给面试官娓娓道来是两码事
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务