一看到这个就 想到链表了,不过写的过程还是略微曲折。
没想到的是最后居然TLE。在leetcode上看到一个很漂亮的代码,但是本地测试耗时是我的近3倍,不知道为什么这个能AC。
我的代码时间复杂度也就是O(n)啊。。。
struct Node{
public:
int val;
Node * next;
Node(int v) :val(v), next(NULL) {}
};
class MyLRUCache{
private:
Node *khead;
Node *vhead;
int capa, count;
public:
MyLRUCache(int capacity) {
khead = NULL;
vhead = NULL;
capa = capacity;
count = 0;
}
int get(int key, bool isSet = false) {
if (count == 0)return -1;
if (khead->val == key)return vhead->val;
if (count == 1)return -1;
int i = 1;
Node *p = khead, *tmp = p;
while (i < count)
{
if (p->next->val == key){
break;
}
i++;
tmp = p;
p = p->next;
}
if (i == count){
if (isSet && count == capa){
p->next = khead;
khead = p;
tmp->next = NULL;
p = vhead;
while (p->next){
tmp = p;
p = p->next;
}
p->next = vhead;
vhead = p;
tmp->next = NULL;
}
return -1;//not found
}
//adjust key list
tmp = p->next->next;
p->next->next = khead;
khead = p->next;
p->next = tmp;
//adjust value list
Node *v = vhead;
int j = 0;
while (j++ < i - 1)v = v->next;
tmp = v->next;
v->next = tmp->next;
tmp->next = vhead;
vhead = tmp;
return vhead->val;
}
void set(int key, int value) {
if (capa == 0)return;
if (count == 0)
{
khead = new Node(key);
vhead = new Node(value);
count++;
return;
}
int res = get(key, true);
if (count < capa && res == -1){
Node *k = new Node(key);
Node *v = new Node(value);
k->next = khead;
v->next = vhead;
khead = k;
vhead = v;
count++;
return;
}
khead->val = key;
vhead->val = value;
return;
}
};
//别人的代码
class LRUCache{
public:
LRUCache(int capacity) {
this->capacity = capacity;
}
int get(int key) {
if (mp.count(key)>0)
{
moveToEnd(key);
return mp[key];
}
return -1;
}
void set(int key, int value) {
if (mp.count(key)>0)
{
mp[key] = value;
moveToEnd(key);
}
else if (mp.size()<capacity)
{
mp[key] = value;
l.push_back(key);
pos[key] = getLast(l);
}
else
{
mp.erase(l.front());
l.pop_front();
mp[key] = value;
l.push_back(key);
pos[key] = getLast(l);
}
}
//change key's literator to list's end in pos
void moveToEnd(int key)
{
l.erase(pos[key]);
l.push_back(key);
list<int>::iterator i = l.end();
i--;
pos[key] = i;
}
list<int>::iterator getLast(list<int> &l)
{
auto it = l.end();
it--;
return it;
}
private:
map<int, int> mp;
map<int, list<int>::iterator> pos;
list<int> l;
int capacity;
};