题解
方法1:全局数据
主要思路
这里不同于传统的哈希表+双向链表的方法,而是只用一个数据结构创建一个数组,数组的长度可以覆盖所有key可能的取值(0到1w),同时数组中的每个元素除去记录每个key对应的value之外,还需要记录此数据是否在cache中,以及他在cache中的前一个元素和后一个元素的数组下标以便于用于更新cache数据。这种方法牺牲了存储空间,但是效率要比哈希表要高
源代码
struct Node{
int nextIndex;
int preIndex;
int value;
};
class LRUCache {
public:
LRUCache(int capacity) {
this->capacity = capacity;
cacheSize = 0;
for(int i = 0; i < 10010; i++)
{
data[i].value = -1;
data[i].nextIndex = -1;
data[i].preIndex = -1;
}
startIndex = -1;
endIndex = -1;
}
int get(int key) {
if(data[key].value == -1)
return -1;
if(startIndex == key)
{
return data[key].value;
}
else if(endIndex == key)
{ //如果获取的数值为末端点,就更换末端点位置
endIndex = data[key].preIndex;
data[data[key].preIndex].nextIndex = data[key].preIndex;
}
else
{ // 如果获取的数值不为末端点,就把此节点前后两个节点连接到一起
int preIndex = data[key].preIndex;
data[preIndex].nextIndex = data[key].nextIndex;
data[data[key].nextIndex].preIndex = preIndex;
}
// 把当前读取的数据放到首位
data[startIndex].preIndex = key;
data[key].nextIndex = startIndex;
data[key].preIndex = key;
startIndex = key;
return data[key].value;
}
void put(int key, int value) {
//之前没在cache中
if(data[key].value == -1)
{
if(cacheSize != 0)
{ //cache中存在数据
data[key].nextIndex = startIndex;
data[key].value = value;
data[key].preIndex = key;
data[startIndex].preIndex = key;
startIndex = key;
}
else
{
data[key].nextIndex = data[key].preIndex = key;
data[key].value = value;
startIndex = key;
endIndex = key;
}
cacheSize++;
}
else if(key == startIndex)
{ //在cache头部, 不用处理
data[key].value = value;
return;
}
else if(data[key].nextIndex == key)
{ //在cache尾部
data[data[key].preIndex].nextIndex = data[key].preIndex;
endIndex = data[key].preIndex;
data[startIndex].preIndex = key;
data[key].preIndex = key;
data[key].nextIndex = startIndex;
startIndex = key;
data[key].value = value;
}
else
{ //在cache中间部分
data[data[key].preIndex].nextIndex = data[key].nextIndex;
data[data[key].nextIndex].preIndex = data[key].preIndex;
data[startIndex].preIndex = key;
data[key].nextIndex = startIndex;
data[key].preIndex = key;
startIndex = key;
data[key].value = value;
}
if(cacheSize > capacity)
{ //超出容量,删除最后一个数据
data[endIndex].value = data[endIndex].nextIndex = -1;
data[data[endIndex].preIndex].nextIndex = data[endIndex].preIndex;
int thisEndIndex = endIndex;
endIndex = data[thisEndIndex].preIndex;
data[thisEndIndex].preIndex = -1;
cacheSize--;
}
}
private:
Node data[10010];
int startIndex;
int endIndex;
int cacheSize;
int capacity;
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/
时空复杂度
- 用时:336 ms, 在所有 C++ 提交中击败了99.10%的用户
- 内存:159.7 MB, 在所有 C++ 提交中击败了95.55%的用户
中途错误记录
- 第一次提交错误:if语句判断
==
写成了=