Question

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.

Solution

My first thought is to use a linked list and a hashmap. But remove and add element for linked list is O(n) per step.

So, the final idea is to implement a bi-directional linked list.

details

For this question, I submitted over 10 times and finally got accepted.

There are many details we need to check.

1. When deleting a node, we should modify both prev and next attributes of its neighbors.

2. Every time when we add a new node, we should check whether it is the first node.

3. When input capacity is 1, we should deal with it separately.

 // Construct double list node
class Node {
public Node prev;
public Node next;
private int val;
private int key;
public Node(int key, int val) {
this.key = key;
this.val = val;
}
public void setValue(int val) {
this.val = val;
}
public int getKey() {
return key;
}
public int getValue() {
return val;
}
} public class LRUCache {
private int capacity;
private Map<Integer, Node> map;
private Node head;
private Node tail; public LRUCache(int capacity) {
this.capacity = capacity;
map = new HashMap<Integer, Node>();
} private void moveToHead(Node target) {
// Check whether target is already at head
if (target.prev == null)
return;
// Check whether target is at tail
if (target == tail)
tail = target.prev;
Node prev = target.prev;
Node next = target.next;
if (prev != null)
prev.next = next;
if (next != null)
next.prev = prev; Node oldHead = head;
target.prev = null;
target.next = oldHead;
oldHead.prev = target;
head = target;
} public int get(int key) {
if (!map.containsKey(key))
return -1;
Node current = map.get(key);
// Move found node to head
moveToHead(current);
return current.getValue();
} public void set(int key, int value) {
if (map.containsKey(key)) {
Node current = map.get(key);
current.setValue(value);
// Move found node to head
moveToHead(current); } else {
Node current = new Node(key, value);
// Add new node to map
map.put(key, current); // Check whether map size is bigger than capacity
if (map.size() > capacity) {
// Move farest used element out
Node last = tail;
map.remove(last.getKey());
// Remove from list
if (map.size() == 1) {
head = current;
tail = current;
} else {
Node oldHead = head;
current.next = oldHead;
oldHead.prev = current;
head = current;
tail = tail.prev;
tail.next = null;
} } else {
// Add new node to list
if (map.size() == 1) {
head = current;
tail = current;
} else {
Node oldHead = head;
current.next = oldHead;
oldHead.prev = current;
head = current;
}
}
}
}
}

LRU Cache 解答的更多相关文章

  1. [LeetCode]LRU Cache有个问题,求大神解答【已解决】

    题目: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the ...

  2. [LeetCode] LRU Cache 最近最少使用页面置换缓存器

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  3. 【leetcode】LRU Cache

    题目简述: Design and implement a data structure for Least Recently Used (LRU) cache. It should support t ...

  4. LeetCode:LRU Cache

    题目大意:设计一个用于LRU cache算法的数据结构. 题目链接.关于LRU的基本知识可参考here 分析:为了保持cache的性能,使查找,插入,删除都有较高的性能,我们使用双向链表(std::l ...

  5. LRU Cache实现

    最近在看Leveldb源码,里面用到LRU(Least Recently Used)缓存,所以自己动手来实现一下.LRU Cache通常实现方式为Hash Map + Double Linked Li ...

  6. 【leetcode】LRU Cache(hard)★

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  7. [LintCode] LRU Cache 缓存器

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  8. LRU Cache [LeetCode]

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  9. 43. Merge Sorted Array && LRU Cache

    Merge Sorted Array OJ: https://oj.leetcode.com/problems/merge-sorted-array/ Given two sorted integer ...

随机推荐

  1. C++中单链表的建立和操作

    准备数据 准备在链表操作中需要用到的变量及数据结构 示例代码如下: struct Data //数据结点类型 { string key; //关键字 string name; int age; }; ...

  2. qt model/view 架构基础介绍之QTableWidget

    # -*- coding: utf-8 -*- # python:2.x #说明:QTreeWidget用于展示树型结构,也就是层次结构同前面说的 QListWidget 类似,这个类需要同另外一个辅 ...

  3. Staple: Complementary Learners For Real-time Tracking Tracking

    转载注明出处: http://www.cnblogs.com/sysuzyq/p/6169414.html By 少侠阿朱 讨论班上的PPT 1.同学大家好.今天给大家讲一篇单目标跟踪的论文,方法比较 ...

  4. Qt使用异或进行加密解密

          在加密,解密中,异或运算应该时比较简单的一种.下面的代码,采用异或运算进行加密,解密: 点击(此处)折叠或打开 #include <QtCore/QCoreApplication&g ...

  5. MYSQL免安装版使用说明

    1>把压缩文件mysql-noinstall-5.1.6-alpha-win32.zip解压到一个目录下,在环境变量中设置MYSQL_HOME,把%MYSQL_HOME%\bin 加入到 pat ...

  6. jQuery数组处理函数

    写在前面: jQuery的数组处理函数整理如下,如有补充和建议,欢迎评论交流~   1.$.trim(value)  从value中删除任何前导或尾随的空白字符   2.$.each(containe ...

  7. javascript 阻止多次点击造成的轮播混乱

    function nextSlider(){ //使用b作为开关,只有动画完成后才能进行下一次运动 if(b){ //如果b为真,则马上设置b为false,如果startmove的回调没有重新设置b的 ...

  8. Android中Binder的基础知识点

    Android Binder基础知识点 一 传统IPC和Binder机制的比较 传统IPC: 1)收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份. 2)接入点开放,无法建立私有通道. ...

  9. (原)error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5577534.html 在debug下使用intel的mkl库时(release下无此问题),莫名的出现 ...

  10. (原)调用jpeglib对图像进行压缩

    网址:http://www.cnblogs.com/darkknightzh/p/4973828.html.未经允许,严禁转载. 参考网站: http://dev.w3.org/Amaya/libjp ...