leetcode146- LRU Cache- hard
Posted jasminemzy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode146- LRU Cache- hard相关的知识,希望对你有一定的参考价值。
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get
and put
.
get(key)
- Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.put(key, value)
- Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
Follow up:
Could you do both operations in O(1) time complexity?
Example:
LRUCache cache = new LRUCache( 2 /* capacity */ ); cache.put(1, 1); cache.put(2, 2); cache.get(1); // returns 1 cache.put(3, 3); // evicts key 2 cache.get(2); // returns -1 (not found) cache.put(4, 4); // evicts key 1 cache.get(1); // returns -1 (not found) cache.get(3); // returns 3 cache.get(4); // returns 4
数据结构:双端链表(自己实现有prev和next的Node) + Map<Key, Node>。Node具体包含(prev, next, key, val)。map具体包含(key值,指过去对应的node)。辅助的全局变量:Node head, tail,记得一开始先让它们两个连上。
辅助的小函数:1.把节点加到最前面。(在创造新节点、更新状态的时候都用到) 2.把某key对应的那个节点拉到最前面(更新的时候用到)。 3.删除最后一个节点(满了以后更新的时候用到)
get:1.更新状态。 2.返回值。
put:三种情况
a)已经有了的话
1.改值。2.更新状态。
b)没有但还有位置
1.造节点。 2.map加映射。 3.插到最前面。
c)没有而且没位置了
1.map删最后的节点。2.list删最后的节点。 3.造结点。4.map加映射。5.插到最前面。
实现:
class LRUCache { private int capacity; private Map<Integer, Node> map; private Node head; private Node tail; private class Node { public int key; public int val; public Node prev; public Node next; public Node(int key, int val) { this.key = key; this.val = val; this.prev = null; this.next = null; } } public LRUCache(int capacity) { this.capacity = capacity; this.map = new HashMap<Integer, Node>(); this.head = new Node(-1, -1); this.tail = new Node(-1, -1); this.head.next = this.tail; this.tail.prev = this.head; } public int get(int key) { if (!map.containsKey(key)) { return -1; } update(key); return map.get(key).val; } public void put(int key, int value) { if (map.containsKey(key)) { map.get(key).val = value; update(key); } else if (map.size() < capacity) { Node node = new Node(key, value); map.put(key, node); addToHead(node); } else { Node lastNode = tail.prev; map.remove(lastNode.key); lastNode.prev.next = tail; tail.prev = lastNode.prev; Node node = new Node(key, value); map.put(key, node); addToHead(node); } return; } private void update(int key) { Node node = map.get(key); node.prev.next = node.next; node.next.prev = node.prev; addToHead(node); } private void addToHead(Node node) { node.prev = head; node.next = head.next; head.next.prev = node; head.next = node; } } /** * Your LRUCache object will be instantiated and called as such: * LRUCache obj = new LRUCache(capacity); * int param_1 = obj.get(key); * obj.put(key,value); */
以上是关于leetcode146- LRU Cache- hard的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode Top 100 Liked Questions 146. LRU Cache (Java版; Medium)