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.
题述如上。
第一次编写的代码,思路是通过引用计数器来实现,功能通过,但又因为要不断地维护这个计数器而效率低下导致未accepted。
public class LRUCache { class Cache { int key; int value; int count; } Cache[] Cc; public LRUCache(int capacity) { Cc = new Cache[capacity]; for (int i = 0; i < Cc.length; i++) { Cc[i] = new Cache(); Cc[i].value = -1; Cc[i].count = i; } } public int get(int key) { for (int i = 0; i < Cc.length; i++) { if (Cc[i].key == key) { if (Cc[i].count != Cc.length - 1) { Cc[i].count = Cc.length - 1; for (int j = 0; j < Cc.length; j++) { Cc[j].count--; } } return Cc[i].value; } } return -1; } public void set(int key, int value) { for (int i = 0; i < Cc.length; i++) { Cc[i].count--; if (Cc[i].count == -1) { Cc[i].key = key; Cc[i].value = value; Cc[i].count = Cc.length - 1; } } } public static void main(String[] args) { LRUCache lru = new LRUCache(10); lru.set(2, 2); lru.set(3, 2); lru.set(11, 9); for (int i = 0; i < lru.Cc.length; i++) { System.out.println(lru.Cc[i].key + "count" + lru.Cc[i].count + "value" + lru.Cc[i].value); } System.out.println(lru.get(11)); } }
class Map { int key; int value; } Map[] map; int capacity; public LRUCache(int capacity) { map = new Map[capacity]; for (int i = 0; i < capacity; i++) { map[i] = new Map(); } this.capacity = capacity; } public int get(int key) { int i = capacity - 1; int result = -1; Map temp = new Map(); while (i > 0) { if (map[i].key == key) { result = map[i].value; temp = map[i]; while (i < capacity - 1) { map[i] = map[i + 1]; i++; } map[capacity - 1] = temp; break; } i--; } return result; } public void set(int key, int value) { int i = 0; while (i < capacity - 1) { map[i].key = map[i + 1].key; map[i].value = map[i + 1].value; i++; } map[capacity - 1].key = key; map[capacity - 1].value = value; }
public class LRUCache { private int capacity; private Map<Integer, Integer> map; public LRUCache(int c) { this.capacity = c; this.map = new LinkedHashMap<Integer, Integer>(capacity, 0.75f, true) { protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) { return size() > capacity; } }; } public int get(int key) { if (!map.containsKey(key)) { return -1; } return map.get(key); } public void set(int key, int value) { map.put(key, value); } }
class Node { int key; int value; Node next; Node pre; Node(int key, int value) { this.key = key; this.value = value; } } int capacity; HashMap<Integer, Node> map; Node head = new Node(-1, -1); Node tail; int size = 0; public LRUCache(int capacity) { this.capacity = capacity; map = new HashMap<Integer, LRUCache.Node>(capacity); } public int get(int key) { Node temp = map.get(key); if (temp == null) { return -1; } else { removeNode(temp); temp = new Node(key, temp.value); addNodetoTail(temp); map.put(key, temp); return temp.value; } } public void set(int key, int value) { Node temp = map.get(key); if (temp == null) { if (size == capacity) { removeHead(); } size++; } else { removeNode(temp); } temp = new Node(key, value); addNodetoTail(temp); map.put(key, temp); } private void removeHead() { // TODO Auto-generated method stub map.remove(head.key); if (size > 1) { head = head.next; head.pre = null; } else { head = null; } size--; } private void removeNode(Node temp) { // TODO Auto-generated method stub if (size > 1) { if (temp.pre != null) {// 证明是head结点 temp.pre.next = temp.next; } else { head = head.next; head.pre = null; } if (temp.next != null)// 证明tail结点 { temp.next.pre = temp.pre; } else { tail = tail.pre; tail.next = null; } } else { tail = null; } } private void addNodetoTail(Node node) { // TODO Auto-generated method stub if (tail == null || head == null) { head = node; tail = node; head.next = tail; tail.pre = head; head.pre = null; tail.next = null; } else { tail.next = node; node.pre = tail; node.next = null; tail = node; } }
public class LRUCache { class Node { int key; int value; Node next; Node pre; Node(int key, int value) { this.key = key; this.value = value; } } class Map { int key; Node value; Map next; Map(int key, Node value) { this.key = key; this.value = value; } Map(int key, Node value, Map next) { this.key = key; this.value = value; this.next = next; } } Map[] mymap; int capacity = 0; Node head = new Node(-1, -1); Node tail; int size = 0; int Mapsize = 1; public LRUCache(int capacity) { this.capacity = capacity; while (Mapsize < capacity) { Mapsize = Mapsize << 1; } mymap = new Map[Mapsize]; } public int get(int key) { int index = key & Mapsize - 1; for (Map e = mymap[index]; e != null; e = e.next) { if (e.key == key) { removeNode(e.value); Node temp = new Node(key, e.value.value); addNodetoTail(temp); e.value = temp; return e.value.value; } } return -1; } public void set(int key, int value) { Node temp = new Node(key, value); int index = key & Mapsize - 1; Map e = mymap[index]; for (; e != null; e = e.next) { if (e.key == key) { removeNode(e.value); e.value = temp; addNodetoTail(temp); return; } } Map next = mymap[index]; mymap[index] = new Map(key, temp, next); if (size == capacity) { removeHead(); } size++; addNodetoTail(temp); } private void removeHead() { // TODO Auto-generated method stub int index = head.key & Mapsize - 1; Map prev = mymap[index]; Map e = prev; while (e != null) { Map next = e.next; if (e.value.key == head.key) { if (prev == e) mymap[index] = next; else prev.next = next; } prev = e; e = next; } if (size > 1) { head = head.next; head.pre = null; } else { head = null; } size--; } private void removeNode(Node temp) { // TODO Auto-generated method stub if (size > 1) { if (temp.pre != null) {// 证明是head结点 temp.pre.next = temp.next; } else { head = head.next; head.pre = null; } if (temp.next != null)// 证明tail结点 { temp.next.pre = temp.pre; } else { tail = tail.pre; tail.next = null; } } else { tail = null; } } private void addNodetoTail(Node node) { // TODO Auto-generated method stub if (tail == null) { head = node; tail = node; head.next = tail; tail.pre = head; head.pre = null; tail.next = null; } else { tail.next = node; node.pre = tail; node.next = null; tail = node; } } public static void main(String[] args) { LRUCache lru = new LRUCache(2); lru.set(1, 1); lru.set(2, 1); get(lru, 4); lru.set(4, 1); get(lru, 1); get(lru, 2); // // for (int i = 0; i < 4; i++) { // get(lru, i); // // } // // get(lru, 5); // // get(lru, 9); // lru.set(8, 4); // // get(lru, 7); // lru.set(8, 5); // get(lru, 3); // lru.set(80, 5); // lru.set(10, 5); // lru.set(11, 5); // lru.set(1123, 5); // lru.set(10, 5); // get(lru, 8); // get(lru, 10); // get(lru, 113); // get(lru, 11); System.out.println("---------------------------------------------"); while (lru.head != null) { System.out.println(lru.head.key + "value" + lru.head.value); lru.head = lru.head.next; } System.out.println("---------------------------------------------" + lru.size); while (lru.tail != null) { System.out.println(lru.tail.key + "value" + lru.tail.value); lru.tail = lru.tail.pre; } // [set(2,1),get(2),set(3,2),get(2),get(3)] // Output: [1,1,-1] // Expected: [1,-1,1] // set(2,1),set(1,1),get(2),set(4,1),get(1),get(2) // System.out.println(8 & 15); } private static void get(LRUCache lru, int key) { System.out.println(lru.get(key) + "key=" + key); } }
int capacity = 0; Node head = new Node(-1, -1); Node tail; int size = 0; int Mapsize = 1; public LRUCache(int capacity) { this.capacity = capacity; while (Mapsize < capacity) { Mapsize = Mapsize << 1; } mymap = new Map[Mapsize]; }在初始化的时候找到大于设置容量的最小的2的n次方。
public void set(int key, int value) { Node temp = new Node(key, value); int index = key & Mapsize - 1; Map e = mymap[index]; for (; e != null; e = e.next) { if (e.key == key) { removeNode(e.value); e.value = temp; addNodetoTail(temp); return; } } Map next = mymap[index]; mymap[index] = new Map(key, temp, next); if (size == capacity) { removeHead(); } size++; addNodetoTail(temp); }set方法也是调试了许久,苦于java不支持指针所以要在map里加一个构造函数, Map(int key, Node value, Map next),将新加入的结点到在链表头。
private void removeHead() { // TODO Auto-generated method stub int index = head.key & Mapsize - 1; Map prev = mymap[index]; Map e = prev; while (e != null) { Map next = e.next; if (e.value.key == head.key) { if (prev == e) mymap[index] = next; else prev.next = next; } prev = e; e = next; } if (size > 1) { head = head.next; head.pre = null; } else { head = null; } size--; }删除头指针,关键代码在于
Map prev = mymap[index]; Map e = prev; while (e != null) { Map next = e.next; if (e.value.key == head.key) { if (prev == e) mymap[index] = next; else prev.next = next; } prev = e; e = next; }
while (Mapsize < capacity*2) { Mapsize = Mapsize << 1; }
原文地址:http://blog.csdn.net/lingchixin/article/details/42319063