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