https://oj.leetcode.com/problems/lru-cache/
这个题目的大体意思是,为LRU设计一种数据结构,使得能够支持get和set操作。
get(key)表示,如果cache里面存在key的value的话,就返回value,否则返回-1;
set(key,value)表示,如果cache里面存在key 的话,就更改key对应的value值,否则就加入新的(key,value)对,
如果(key,value)对的个数超过cache的容量的话,就删除最不经常使用的(key,value)对,加入新的(key,value)对。
首先我使用的是双向链表做的。时间复杂度是O(n^2)。是超时的。
代码如下:
public class LRUCache {
class Node
{
int key;
int value;
Node next;
Node preNode;
public Node() {
// TODO Auto-generated constructor stub
next = null;
}
public Node(int k,int v)
{
key = k;
value = v;
next = null;
preNode =null;
}
}
int Capacity;
int currentCount=0;
Node head;
Node tail;
public LRUCache(int capacity) {
Capacity = capacity;
currentCount = 0;
head = new Node();
tail = head;
}
public int get(int key) {
if(currentCount==1)
{
if(head.next.key==key)
return head.next.value;
}
if(Capacity>1){
Node tempNode = head.next;
while(tempNode!=null)
{
if(tempNode.key == key)
{
if(tempNode==head.next)
return tempNode.value;
if(tempNode==tail)
{
tail = tail.preNode;
}
tempNode.preNode.next = tempNode.next;
if(tempNode.next!=null)
{
tempNode.next.preNode = tempNode.preNode;
}
tempNode.next = head.next;
tempNode.next.preNode = tempNode;
tempNode.preNode = head;
head.next =tempNode;
return tempNode.value;
}
tempNode = tempNode.next;
}
}
return -1;
}
public void set(int key, int value) {
int getkey=get(key);
if(getkey!=-1)
{
head.next.value = value;
return;
}
if(Capacity>currentCount){
if(currentCount == 0){
head.next = new Node(key,value);
head.next.preNode = head;
tail = tail.next;
}
else {
Node tempNode = new Node(key,value);
tempNode.next = head.next;
tempNode.next.preNode = tempNode;
tempNode.preNode = head;
head.next = tempNode;
}
currentCount++;
}
else {
Node tempNode = new Node(key,value);
tempNode.next = head.next;
tempNode.next.preNode = tempNode;
tempNode.preNode = head;
head.next = tempNode;
tail = tail.preNode;
tail.next = null;
}
}
}
为了优化算法,我使用了双向链表+散列表的方法。时间复杂的是O(n)。
public class LRUCache {
class Node{
int key;
int value;
Node next;
Node preNode;
public Node(int k,int v){
key = k;
value = v;
next = null;
preNode = null;
}
}
int Capacity;
int currentCount=0;
Node head;
Node tail;
HashMap<Integer, Node>map;
public LRUCache(int capacity) {
Capacity = capacity;
currentCount = 0;
head = new Node(-1,-1);
tail = head;
map = new HashMap<Integer,Node>();
map.clear();
}
public void putHead(Node tempNode){
if(tempNode==head.next)return;
if(tempNode == tail){
tail = tail.preNode;
tempNode.preNode = null;
tail.next = null;
}
else{
tempNode.preNode.next = tempNode.next;
tempNode.next.preNode = tempNode.preNode;
}
tempNode.next = head.next;
head.next.preNode = tempNode;
tempNode.preNode = head;
head.next = tempNode;
}
public int get(int key) {
if(map.containsKey(key)){
Node getNode = map.get(key);
putHead(getNode);
return getNode.value;
}
else {
return -1;
}
}
public void set(int key, int value) {
Node getNode = map.get(key);
if(getNode==null){
Node tempNode = new Node(key, value);
map.put(key, tempNode);
if(currentCount<Capacity){
if(currentCount == 0){
head.next = tempNode;
tempNode.preNode = head;
tail = tempNode;
}
else {
tempNode.next = head.next;
head.next.preNode = tempNode;
head.next = tempNode;
tempNode.preNode = head;
}
currentCount++;
}
else {
map.remove(tail.key);
tail = tail.preNode;
tail.next.preNode = null;
tail.next = null;
tempNode.next = head.next;
if(head.next!=null){
head.next.preNode = tempNode;
}
tempNode.preNode = head;
head.next = tempNode;
}
}
else {
putHead(getNode);
getNode.value = value;
}
}
}