Leetcode 146. LRU 缓存(Hashmap+双链表)

这篇具有很好参考价值的文章主要介绍了Leetcode 146. LRU 缓存(Hashmap+双链表)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目描述

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
● LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
● int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
● void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

测试用例

示例1

输入
[“LRUCache”, “put”, “put”, “get”, “put”, “get”, “put”, “get”, “get”, “get”] [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]
解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4

解法

解法:双链表+HashMap

HashMap:

Key Value
1 node1
2 node2

双链表:

(head)[ | ] -><- (node1)[ 1 | value1 ] -><- (node2)[ 2 | value2 ] -><- (tail)[ | ]文章来源地址https://www.toymoban.com/news/detail-564563.html

class LRUCache {
    /**
	  定义双向链表类
	*/
    class DoubleLinkedNode {
        int key, value;
        DoubleLinkedNode prev, next;
        DoubleLinkedNode () {
            
        }
        DoubleLinkedNode (int _key, int _value) {
            key = _key;
            value = _value;
        }
    }
    /**
      size为存放数据长度, capacity为最大缓存容量
    */
    private int size, capacity;
    /**
        双向链表头节点和尾节点
    */
    private DoubleLinkedNode head, tail;
    private Map<Integer, DoubleLinkedNode> map = new HashMap<>();
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.size = 0;
        head = new DoubleLinkedNode();
        tail = new DoubleLinkedNode();
        head.next = tail;
        tail.next = head;
    }
    
    public int get(int key){
        if (size <= 0) {
            return -1;
        }
        DoubleLinkedNode node = map.get(key);
        if (node == null) {
            // LRU中不存在元素
            return -1;
        } else {
            // LRU中存在元素
            // 将元素移到head处,表示已访问过
            moveToHead(node);
            return node.value;
        }
    }

    public void put(int key, int value) {
        // 判断是否已经存在该节点
        DoubleLinkedNode node = map.get(key);
        if (node == null) {
            // 节点为空,直接放入
            // 生成节点
            DoubleLinkedNode newNode = new DoubleLinkedNode(key, value);
            // 存放到头部, 最近访问
            addToHead(newNode);
            // map加上该节点
            map.put(key, newNode);
            size++;
            // 判断数据长度是否大于最大的LRU容量
            if (size > capacity) {
                // 移除出LRU
                DoubleLinkedNode tailRemoved = removeTail();
                // map相应移出该元素
                map.remove(tailRemoved.key);
                size--;
            }
        } else {
            // 变更数据值value
            node.value = value;
            // 移动到头部,最近访问
            moveToHead(node);
        }
    }

    private void addToHead (DoubleLinkedNode node) {
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
        node.prev = head;
    }
    /**
     移动节点到head处
    */
    private void moveToHead (DoubleLinkedNode node) {
        // 先移出
        // 前一个元素指向后一个元素
        node.prev.next = node.next;
        // 后一个元素指向前一个元素
        node.next.prev = node.prev;
        // 再放入
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
        node.prev = head;
    }

    private DoubleLinkedNode removeTail () {
        DoubleLinkedNode p = tail.prev;
        tail.prev.prev.next = tail;
        tail.prev = p.prev;
        return p;
    }
}

到了这里,关于Leetcode 146. LRU 缓存(Hashmap+双链表)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • leetcode做题笔记146. LRU 缓存

    请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。 实现  LRUCache  类: LRUCache(int capacity)  以  正整数  作为容量  capacity  初始化 LRU 缓存 int get(int key)  如果  key  存在于缓存中,则返回的值,否则返回  -1  。 void put(int key, int value)  如果

    2024年02月07日
    浏览(37)
  • 【数据结构】LRU缓存的简单模拟实现(leetcode力扣146LRU缓存)

    LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。 Cache的容量有限,因此当Cache的容量用完后,而又有新的内容需要添加进来时, 就需要挑选并舍弃原有的部分内容,从而腾出空间来放新内容。LRU Cache 的替换原则就是将最近最少使用的内容替换掉。

    2024年02月03日
    浏览(43)
  • 二刷LeetCode--146.LRU缓存(C++版本),必会题目

    本题思路:因为需要记录元素的出入顺序,并且每次访问之后需要将该节点提到最前面,因此需要使用双向链表(单链表不方便删除操作),而为了可以在常量时间复杂度内找到对应的元素,我们需要使用哈希表,将每一个插入的元素在哈希表中进行记录.哈希表的key就是插入的key,而哈希

    2024年02月13日
    浏览(38)
  • [力扣146. LRU 缓存 ](https://leetcode.cn/problems/lru-cache/description/)

    力扣146. LRU 缓存 使用LinkedHashmap(HashMap的子类,能够记住插入数据的顺序). LRU是Lease Recently User的缩写,意思是最近 最少使用。比如设计一个文件缓存系统,每个文件有自己的大小和访问时间,文件缓存系统有总的大小,当往这个文件系统中放入新的文件时,如果发现超出文件

    2024年02月11日
    浏览(51)
  • 每日两题 / 142. 环形链表 II & 146. LRU 缓存(LeetCode热题100)

    142. 环形链表 II - 力扣(LeetCode) 用哈希记录走过的节点即可 146. LRU 缓存 - 力扣(LeetCode) O ( 1 ) O(1) O ( 1 ) 地查找并修改kv结构,用unordered_map即可解决 问题是题目要求:哈希表容量有限,超出容量时,将删除最久未访问的kv 那么关键就在于:如何用数据结构表示访问的先后顺

    2024年04月16日
    浏览(41)
  • 146. LRU 缓存

    请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果 key 存在于缓存中,则返回的值,否则返回 -1 。 void put(int key, int value) 如果 key 已经存在,

    2024年02月12日
    浏览(46)
  • LeetCode刷题---LRU缓存

    LRU是Least Recently Used的缩写,即最近最少使用,是一种内存管理算法,也可以用作缓存淘汰策略。 这种算法的核心思想是:如果数据最近被访问过,那么将来被访问的几率也更高。 因此,当内存或缓存容量有限,需要淘汰部分数据时,LRU算法会优先淘汰那些最长时间未被访问

    2024年02月22日
    浏览(37)
  • (力扣记录)146. LRU 缓存

    数据类型 :链表 时间复杂度: O(1) 空间复杂度: O(N) 代码实现:

    2024年01月18日
    浏览(41)
  • 【leetcode100-035】【链表/哈希链表】LRU缓存

    【题干】 请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。 实现  LRUCache  类: LRUCache(int capacity)  以  正整数  作为容量  capacity  初始化 LRU 缓存 int get(int key)  如果  key  存在于缓存中,则返回的值,否则返回  -1  。 void put(int key, in

    2024年02月01日
    浏览(43)
  • 146. LRU Cache最近最少使用 (LRU) 缓存 Least Recently Used (LRU) cache.

    Design a data structure that follows the constraints of a Least Recently Used (LRU) cache. Implement the LRUCache class: LRUCache(int capacity) Initialize the LRU cache with positive size capacity. int get(int key) Return the value of the key if the key exists, otherwise return -1. void put(int key, int value) Update the value of the key if the key exists. O

    2024年02月10日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包