题目链接:https://leetcode.com/problems/lru-cache/ 题目:
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. set(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.
思路:
用链表存储key的顺序关系,不管是用栈还是队列,在get元素和set已有元素时候,需要remove链表中的元素,如果用Java 内置的链表,时间复杂度为O(n)。 会超时。
如果我们用HashMap保存每个key对应的链表结点的指针,那么remove的时候就可以根据key获取相应的指针,时间复杂度为O(1)。因为涉及到链表的删除,我们以前总结过,有头结点可以简化判断,又因为删除需要知道被删除结点的前后指针,所以用双向链表。又为了简化对尾结点删除的判断,加一个尾结点。
算法 :
class Node { Node pre, next; int key, value; Node(int key, int value, Node pre, Node next) { this .key = key; this .value = value; this .pre = pre; this .next = next; } } HashMap<Integer, Node> maps = new HashMap<Integer, Node>(); int capacity = 0 ; Node head = null ; Node rear = null ; public LRUCache( int capacity) { this .capacity = capacity; head = new Node( 0 , 0 , null , null ); rear = new Node( 0 , 0 , null , null ); head.next = rear; rear.pre = head; } public int get( int key) { if (maps.containsKey(key)) { Node node = maps.get(key); node.pre.next = node.next; node.next.pre = node.pre; node.next = head.next; head.next.pre = node; head.next = node; node.pre = head; return node.value; } else { return - 1 ; } } public void set( int key, int value) { if (maps.containsKey(key)) { Node delete = maps.get(key); delete.pre.next = delete.next; delete.next.pre = delete.pre; } else if (maps.size() == capacity) { maps.remove(rear.pre.key); rear.pre.pre.next = rear; rear.pre = rear.pre.pre; rear.next = null ; } Node node = new Node(key, value, null , null ); node.next = head.next; head.next.pre = node; head.next = node; node.pre = head; maps.put(key, node); }