[LeetCode]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.

LRU Cache

LRU是Least Recent Used的缩写,即最少使用的Cache置换算法,是为虚拟页式存储管理服务的。

Cache是高速缓存,这是IT行业经常见到的概念。CPU中的Cache能极大提高存取指令和数据的时间,让整个存储器(Cache+内存)既有Cache的高速度,又有内存的大容量。

Cache虽然速度快,但是容量有限。因此当Cache容量用完而又有新的内容添加进来的时候,就需要选取Cache中的部分内容进行舍弃,然后添加新的内容。LRU Cache的替换规则是:每次选取最久不被使用的内容进行舍弃,然后添加新的内容。之前上操作系统,老师告诉我的LRU Cache Algorithm中文翻译是最近最久未使用算法。

思路

LRU的典型实现是double linked list + hash map。

双向链表根据每个节点最近被访问的时间有序存储,最近被访问的节点存储在表头,最近没有被访问的节点存储的表尾,存储依据是因为:最近被访问的节点在接下来的一段时间仍有很大的概率被再次访问到。

哈希表的作用是用来提高查找效率,如果不使用哈希表,则查找一个节点的时间复杂度是O(n),而使用了哈希表,则每个节点的查找时间复杂度为O(1)。

查找(GET)操作:

  • 根据键值查找hashmap,如果没找到直接返回-1
  • 若找到对应节点node,则将其插入到双向链表表头
  • 返回node的value值

插入(SET)操作:

  • 根据键值查找hashmap。如果找到,则直接将该节点移到表头即可
  • 如果没有找到,首先判断当前Cache是否已满
  • 如果已满,则删除表尾节点
  • 将新节点插入到表头

AC代码

import java.util.HashMap;

public class LRUCache {
    /**
     * 声明双向链表节点
     *
     * @author wzy
     *
     */
    private static class DoubleListNode {
        DoubleListNode pre;
        DoubleListNode next;
        int value;
        int key;

        public DoubleListNode(int key, int value) {
            this.key = key;
            this.value = value;
            this.pre = this.next = null;
        }
    }

    private HashMap<Integer, DoubleListNode> hashMap;

    private DoubleListNode head;

    private DoubleListNode tail;

    private int capacity;

    private int currentSize;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.currentSize = 0;
        hashMap = new HashMap<Integer, LRUCache.DoubleListNode>(capacity);
        this.head = this.tail = null;
    }

    public int get(int key) {
        DoubleListNode res = hashMap.get(key);

        if (res != null) {
            moveNodeToHead(res);
            return res.value;
        } else {
            return -1;
        }
    }

    public void set(int key, int value) {
        DoubleListNode node = hashMap.get(key);

        if (node == null) {
            node = new DoubleListNode(key, value);

            if (currentSize >= capacity) {
                hashMap.remove(tail.key);
                removeNodeFromTail();
            } else {
                currentSize++;
            }
        } else {
            node.value = value;
        }

        if (currentSize == 1) {
            head = node;
            tail = node;
        }

        moveNodeToHead(node);
        hashMap.put(key, node);
    }

    private void moveNodeToHead(DoubleListNode node) {
        if (node == head) {
            return;
        }

        if (node.next != null) {
            node.next.pre = node.pre;
        }

        if (node.pre != null) {
            node.pre.next = node.next;
        }

        if (node == tail) {
            tail = node.pre;
        }

        if (head != null) {
            node.next = head;
            head.pre = node;
        }

        head = node;
        node.pre = null;
    }

    private void removeNodeFromTail() {
        if (tail != null) {
            if (tail.pre != null) {
                tail.pre.next = null;
            } else {
                head = null;
            }

            tail = tail.pre;
        }
    }

    public static void main(String[] args) {
        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));
    }
}

[LeetCode]LRU Cache, 解题报告

时间: 2024-10-10 01:49:31

[LeetCode]LRU Cache, 解题报告的相关文章

[leetcode]LRU Cache @ Python

原题地址:http://oj.leetcode.com/problems/lru-cache/ 题意:设计LRU Cache 参考文献:http://blog.csdn.net/hexinuaa/article/details/6630384 这篇博文总结的很到位.   https://github.com/Linzertorte/LeetCode-in-Python/blob/master/LRUCache.py 代码参考的github人写的,思路非常清晰,写的也很好. Cache简介: Ca

[leetcode]LRU Cache (python)

LRU:最近最久未使用,为了得到这个最新最久的信息,需要一种策略来进行记录,如果加入类似时间戳式的字段,那么每次删除的时候,就必须通过遍历才能得到时间信息,或者对时间戳进行排序,但是无论哪种,都是需要额外的维护,维护成本都比较高. 广泛使用的策略是底层用双端队列来进行维护,双端使得在插入删除时操作更简单.而单单使用双端队列似乎还是不够,比如在get 时,还是需要顺序查找给定的key参数的,所以为了能在O(1) 时间获得key 需要类hash的结构,在python里,就用字典. 接下来的事情是,我

LeetCode: LRU Cache [146]

[题目] 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

LeetCode: Combination Sum 解题报告

Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Question Solution Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The

【LeetCode】Subsets 解题报告

[题目] Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If S = [1,2,3], a solution is: [ [3], [1], [2], [1,2,

[LeetCode]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.

【LeetCode】LRU Cache 解决报告

插话:只写了几个连续的博客,博客排名不再是实际"远在千里之外"该.我们已经进入2一万内. 再接再厉.油! 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 ke

LeetCode——LRU Cache

Description: 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 r

[LeetCode] 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