首页 > 试题广场 >

LRU缓存

[编程题]LRU缓存
  • 热度指数:407 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作:
获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回-1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。
要求get和put都为O(1)的时间复杂度。

输入描述:
第一行是两个整数N,M。代表共有N次操作,缓存容量为M,用空格分隔。

第2~n+1行是n次操作,格式为"PUT x y"或"GET x"。x和y为题面所要求的数字。


输出描述:
对于每个GET操作,输出一行数字作为结果。
示例1

输入

9 2
PUT 1 1
PUT 2 2
GET 1
PUT 3 3
GET 2
PUT 4 4
GET 1
GET 3
GET 4

输出

1
-1
-1
3
4

说明

PUT 1 1
PUT 2 2
GET 1 // 输出1
PUT 3 3 // 密钥2失效
GET 2 // 未找到
PUT 4 4 // 密钥1失效
GET 1 // 未找到
GET 3 // 输出3
GET 4 // 输出4

备注:
x和y都是正整数,1<=n<=1e5,1<=m<=1e5
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int capacity = scanner.nextInt();
        String[] commands = new String[n];
        LRUCache lru = new LRUCache(capacity);
        //因为第一行输入的命令和第二行输入的命令是换行的
        //所以我们要多加一个nextLine()去吸收那个空格
        scanner.nextLine();
        for(int i = 0; i < n; i++){
            commands[i] = scanner.nextLine();
        }
        
        for(String command : commands){
            String[] s = command.split(" ");
            if(s.length == 2){
                System.out.println(lru.get(Integer.parseInt(s[1])));
            }
            else{
                lru.put(Integer.parseInt(s[1]),Integer.parseInt(s[2]));
            }
        }                
    }
}

class LRUCache{
    
    static class BinaryListNode{
        int key;
        int val;
        BinaryListNode next;
        BinaryListNode prev;
        BinaryListNode(){}
        BinaryListNode(int key, int val){this.key = key; this.val = val;}
    }
    
    private int size;
    private int capacity;
    private BinaryListNode dummyHead;
    private BinaryListNode dummyTail;
    private Map<Integer, BinaryListNode> cache = new HashMap<>();
    
    public LRUCache(int capacity){
        this.size = 0;
        this.capacity = capacity;
        dummyHead = new BinaryListNode();
        dummyTail = new BinaryListNode();
        dummyHead.next = dummyTail;
        dummyTail.prev = dummyHead;
    }
    
    public int get(int key){
        if(!cache.containsKey(key)){
            return -1;
        }
        BinaryListNode node = cache.get(key);
        removeToHead(node);
        return node.val;
    }
    
    public void put(int key, int value){
        if(!cache.containsKey(key)){
            BinaryListNode newNode = new BinaryListNode(key,value);
            cache.put(key,newNode);
            addToHead(newNode);
            size++;
            if(size > capacity){
                BinaryListNode node = removeTail();
                cache.remove(node.key);
                size--;
            }
        }
        else{
            BinaryListNode node = cache.get(key);
            node.val = value;
            removeToHead(node);
        }
    }
    
    public void addToHead(BinaryListNode node){
        node.next = dummyHead.next;
        node.prev = dummyHead;
        dummyHead.next.prev = node;
        dummyHead.next = node;
    }
    
    public void removeNode(BinaryListNode node){
        node.next.prev = node.prev;
        node.prev.next = node.next;
    }
    
    public void removeToHead(BinaryListNode node){
        removeNode(node);
        addToHead(node);
    }
    
    public BinaryListNode removeTail(){
        BinaryListNode tail = dummyTail.prev;
        removeNode(tail);
        return tail;
    }    
}

编辑于 2021-07-23 14:21:20 回复(0)
import java.util.*;
public class Main {

    public static void main(String[] args){
        Scanner input=new Scanner(System.in);
        String line = input.nextLine();
        String[] nums = line.split(" ");
        int N=Integer.parseInt(nums[0]);
        int M=Integer.parseInt(nums[1]);
        LRUCache cache = new LRUCache(M);
        for(int i=0;i<N;i++){
            String str=input.nextLine();
            String[] s = str.split(" ");
            if(str.startsWith("PUT")){
                cache.put(Integer.parseInt(s[1]),Integer.parseInt(s[2]));
            }else {
                System.out.println(cache.get(Integer.parseInt(s[1])));
            }
        }
    }

    static class LRUCache extends LinkedHashMap<Integer,Integer>{
        private int capacity;

        public LRUCache(int capacity) {
            //第三个参数代表可以按访问元素的顺序排序
            super(capacity,0.75F,true);
            this.capacity=capacity;
        }


        public int get(int key) {
            return super.getOrDefault(key,-1);
        }


        public void put(int key, int value) {
            super.put(key,value);
        }

        @Override
        protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
            return size() > capacity;
        }
    }

}
发表于 2020-03-21 13:42:12 回复(0)