LRU Cache(LeetCode)

来源:互联网 发布:数据字典的功能 编辑:程序博客网 时间:2024/05/22 01:31

题目:

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.



思路

  1. 本题的难点在于,这是一个map(有key和value两个项),有时需要将中间某个pair删掉或者移到最后
    • 如果用数组做,移动会很麻烦
  2. 利用LinkedHashMap类实现一个哈希表
    • 之所以用LinkedHashMap而不用HashMap,是因为LinkedHashMap中有个removeEldestEntry方法可以直接用来去掉LRU(最久远用过的)的pair
  3. removeEldestEntry方法
    • 是LinkedHashMap中的一个方法,每当LinkedHashMap类需要“put”或者“putAll”时,都会自动调用removeEldestEntry方法
    • 当removeEldestEntry返回false时,LinkedHashMap会自动扩展容量,加入“put”的pair;当返回true时,会删掉LRU的pair,再加入新pair;
    • LinkedHashMap默认,任何时候removeEldestEntry返回都是false,所以需要覆盖该方法以控制cache的容量
    • 覆盖removeEldestEntry方法,可以直接在实例化LinkedHashMap类型的时候进行,即map = new LinkedHashMap(){...};



注意点:

  1. 当已有的pair被get的时候,需要把这个pair放到map的最后面
  2. 使用了泛型,规定了key和value只能是整型


代码:

import java.util.*;public class LRUCache {static int cap;    static LinkedHashMap<Integer,Integer> map;    public LRUCache(int capacity) {cap = capacity;map = new LinkedHashMap<Integer,Integer>(){    //extend the method "removeEldestEntry"protected boolean removeEldestEntry(Map.Entry eldest){    //The methods "put" and "putAll" will invoke the "removeEldestEntry"    //if method "removeEldestEntry" returns true,     //the LinkedHashMap will remove the least recently used map entry    //before insert an entryreturn size() > cap;}};    }        public int get(int key) {    if (!map.containsKey(key)){    return -1;    }else{        int val = map.get(key);        //the entry pair(key,val) should be moved to the end of the map,        //because it is right now the most recently used    map.remove(key);    map.put(key,val);    return val;    }    }        public void set (int key, int value){    if (map.containsKey(key)){    map.remove(key);    }    map.put(key,value);    }    }



其他方法:

之前尝试过,用两个LinkedList来解决这个问题。一个LinkedList来记录key,另一个记录value。在eclipse上可以得到正确的结果。但是在LeetCode上会TimeLimitedExceed。

方法中,主要用到了LinkedList类中,一些基本的方法,indexOf, remove, get, addLast等等。很简单,贴代码如下:

import java.util.LinkedList;public class LRUCache {static LinkedList<Integer> keyList;static LinkedList<Integer> valueList;int cap;        public LRUCache(int capacity) {cap = capacity;keyList = new LinkedList<Integer>();valueList = new LinkedList<Integer>();    }        public int get(int key) {        int index = keyList.indexOf(key);if (index == -1){return -1;}else{int val = valueList.get(index);keyList.remove(index);valueList.remove(index);keyList.addLast(key);valueList.addLast(val);return val;}    }        public void set (int key, int value){        int index;index = keyList.indexOf(key);if (index != -1){keyList.remove(index);valueList.remove(index);}keyList.addLast(key);valueList.addLast(value);if (keyList.size() > cap){keyList.removeFirst();valueList.removeFirst();}    }    }



0 0