[LeetCode]LRU Cache
Posted jzssuanfa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode]LRU Cache相关的知识,希望对你有一定的参考价值。
题目:实现一个LRU Cache
算法:
- 双向链表 + HashMap
- get:若节点不存在,返回-1;否则返回节点value。并将节点调整到head
- set(key, value):
- 若key已经存在:更新value。并将节点调整到head;
- 若key不存在:若cache容量足够。将节点压入链表头部;若cache容量不足。淘汰链表尾部节点。并将新节点压入链表头部
import java.util.HashMap; public class LRUCache { /** * Structure * * @author ouyangyewei */ public class CacheNode { public int key; public int value; public CacheNode prev; public CacheNode next; public CacheNode() { // nothing } public CacheNode(int key, int value) { this.key = key; this.value = value; this.prev = null; this.next = null; } } private int capacity; private int currentCapacity; private CacheNode head; private CacheNode tail; private HashMap<Integer, CacheNode> hashNode; public LRUCache(int capacity) { this.capacity = capacity; this.currentCapacity = 0; this.head = null; this.tail = null; this.hashNode = new HashMap<Integer, CacheNode>(); } public int get(int key) { CacheNode node = hashNode.get(key); if (null == node) { return -1; } else { moveToHead(node); return node.value; } } public void set(int key, int value) { if (null == hashNode.get(key)) { /** cacheNode is not exists! */ CacheNode node = new CacheNode(key, value); if (currentCapacity < capacity) { /** enough capacity for add a node */ addToHead(node); ++currentCapacity; } else { /** over the maximum capacity */ removeLeastUseNode(); addToHead(node); currentCapacity = capacity; } hashNode.put(key, node); } else { /** cacheNode is already exists */ CacheNode node = hashNode.get(key); node.value = value; moveToHead(node); hashNode.put(key, node); } } /** * Move a node to list's head * @param node */ public void moveToHead(CacheNode node) { if (null != node.prev) { /** node locate behind the list's head */ CacheNode front = node.prev; CacheNode behind = node.next; if (null == behind) { /** node locate at the list's tail */ front.next = behind; tail = front; } else { front.next = behind; behind.prev = front; } node.prev = null; node.next = head; head.prev = node; head = node; } } /** * Add a node to list's head. * @param node */ public void addToHead(CacheNode node) { if (null == head) { /** list is empty */ head = node; tail = node; } else { /** list is not empty */ node.next = head; head.prev = node; head = node; } } /** * Remove the least use node, it means remove * the list's tail node. */ public void removeLeastUseNode() { if (null != tail.prev) { hashNode.remove(tail.key); tail = tail.prev; tail.next = null; } else { /** list has only one node */ hashNode.remove(tail.key); head = null; tail = null; } } // public static void main(String[] args) { // LRUCache lruCache = new LRUCache(4); // lruCache.set(1, 1); // lruCache.set(0, 0); // lruCache.get(1); // lruCache.get(0); // lruCache.set(2, 2); // lruCache.set(4, 4); // lruCache.get(1); // lruCache.get(0); // lruCache.get(0); // lruCache.set(8, 8); // lruCache.set(7, 7); // lruCache.set(5, 5); // lruCache.set(4, 4); // lruCache.set(3, 3); // lruCache.set(2, 2); // lruCache.get(3); // lruCache.get(4); // LRUCache lruCache = new LRUCache(1); // lruCache.set(2, 1); // System.out.println(lruCache.get(2)); // lruCache.set(3, 2); // System.out.println(lruCache.get(2)); // System.out.println(lruCache.get(3)); // LRUCache lruCache = new LRUCache(2); // lruCache.set(2, 1); // lruCache.set(1, 2); // lruCache.set(2, 3); // lruCache.set(4, 1); // System.out.println(lruCache.get(1)); // System.out.println(lruCache.get(2)); // } }
以上是关于[LeetCode]LRU Cache的主要内容,如果未能解决你的问题,请参考以下文章