算法-146. LRU缓存机制

题目:LRU缓存机制

1. 题目描述

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。

获取数据 get(key) - 如果关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字/值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

进阶:

你是否可以在 O(1) 时间复杂度内完成这两种操作?

2. 解题:双链表+HashMap

新建链表类存储节点的访问顺序,使用HashMap存储包含的关键字。

  1. 插入操作
    插入操作判断容量是否超限或者已经包含有关键字,如果包含关键字则直接设置value为输入值,获取关键字节点,将节点移至链表的尾端。如果插入插入的key不存在:1. 容量未超限或容量为空,新建节点放置到链表的尾端,且将(key, Node)放置到HashMap中;2.容量已经达到最大值,从双链表中取下头结点,从HashMap中移除头结点的key,利用取下节点设置新节点的key, value。插入到双链表的尾部,且放入hashMap。

  2. 查询操作
    查询操作,如果HashMap中不存在查询的key则直接返回-1。如果存在查询的key,则将与之对应的双链表节点取下,放置到双链表的尾部,返回对应的value。
    具体代码如下:

    class LRUCache {
    
     static class Node{
         int value, key;
         Node next;
         Node pre;
         public Node(int key, int value){
             this.key = key;
             this.value = value;
         }
     }
     Node head;
     Node tail;
     int capacity;
     int size;
    
     HashMap<Integer, Node> map = new HashMap<>();
     public LRUCache(int capacity) {
         this.capacity = capacity;
     }
    
     public int get(int key) {
         if (map.containsKey(key)) {
             Node node = map.get(key);
             reconnect(node);
             return node.value;
         }
         return -1;
     }
    
     public void put(int key, int value) {
         if(map.containsKey(key)){
             Node node = map.get(key);
             node.value = value;
             reconnect(node);
         }else{
             Node node = null;
             if(size == capacity){
                 node  = head;
                 map.remove(node.key);
                 node.value = value;
                 node.key = key;
                 if(capacity > 1){
                     head = head.next;
                     head.pre = null;
                     node.pre = tail;
                     tail.next = node;
                     tail = node;
                     node.next = null;
                 }
                 map.put(key, node);                
             }else{
                 if(size == 0){
                     node = new Node(key, value);
                     head = node;
                     tail= node;
                 }else{
                     node = new Node(key, value);
                     node.pre = tail;
                     tail.next = node;
                     tail = node;
                 }
                 ++size;
             }
             map.put(key, node);
         }
     }
    
     private void reconnect(Node node){
         if(node == head && size != 1){
             head = head.next;
             node.next = null;
             head.pre = null;
             tail.next = node;
             node.pre = tail;
             tail = node;
         }else if(node != tail && size != 1){
             Node temp = node.next;
             node.pre.next = temp;
             temp.pre = node.pre;
             node.next = null;
             tail.next = node;
             node.pre = tail;
             tail = node;
         }
     }
    }
    
    

~

全部评论

相关推荐

04-06 11:24
已编辑
太原学院 C++
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务