1、题目
设计LRU缓存结构,该结构在构造时确定大小,假设大小为K,并有如下两个功能
set(key, value):将记录(key, value)插入该结构
get(key):返回key对应的value值
[要求]
set和get方法的时间复杂度为O(1)
某个key的set或get操作一旦发生,认为这个key的记录成了最常使用的。
当缓存的大小超过K时,移除最不经常使用的记录,即set或get最久远的。
若opt=1,接下来两个整数x, y,表示set(x, y)
若opt=2,接下来一个整数x,表示get(x),若x未出现过或已被移除,则返回-1
对于每个操作2,输出一个答案
2、解题
时间复杂度为O(1),暂时想到的方法是map+双向链表
class Solution {
public:
/**
* lru design
* @param operators int整型vector<vector<>> the ops
* @param k int整型 the k
* @return int整型vector
*/
struct Node{
int key;
int val;
Node* pre;
Node* next;
};
map<int,Node*> keyToNode;
vector<int> LRU(vector<vector<int> >& operators, int k) {
// write code here
Node* head = NULL;
Node* end = NULL;
int len = 0;
vector<int> result;
if(operators.size() == 0 || k <= 0)return result;
for(int i = 0;i<operators.size();i++){
if(operators[i][0] == 1){
Set(operators[i][1],operators[i][2],&head,&end,len,k);
}else{
Get(operators[i][1],&head,&end,result);
}
}
return result;
}
void Set(int key ,int val,Node** head,Node** end,int &len,int k){
//key不存在
if(keyToNode.find(key) == keyToNode.end()){
//创建节点
Node* tmp = (Node*)malloc(sizeof(Node));
tmp->key = key;
tmp->val = val;
tmp->pre = NULL;
tmp->next = NULL;
//链接
if(*head == NULL){
*head = *end = tmp;
}else{
tmp->next = *head;
(*head)->pre = tmp;
tmp->pre = NULL;
*head = tmp;
}
keyToNode[key] = tmp;
len++;
if(len > k){
//删除最后一个节点
keyToNode.erase((*end)->key);
*end = (*end)->pre;
if(*end == NULL){
*head = NULL;
}else{
(*end)->next = NULL;
}
len--;
}
}else{
//key存在
DealPos(key,head,end);
}
return;
}
void Get(int key,Node** head,Node** end,vector<int> &res){
if(keyToNode.find(key) == keyToNode.end()){
res.push_back(-1);
}else{
res.push_back(keyToNode[key]->val);
DealPos(key,head,end);
}
}
//处理node位置
void DealPos(int key,Node** head,Node** end){
if(keyToNode[key] == *head){
//头节点
return;
}else if(keyToNode[key] == *end){
//尾节点
*end = keyToNode[key]->pre;
keyToNode[key]->pre->next = NULL;
keyToNode[key]->next = *head;
(*head)->pre = keyToNode[key];
keyToNode[key]->pre = NULL;
*head = keyToNode[key];
}else{
keyToNode[key]->pre->next = keyToNode[key]->next;
keyToNode[key]->next->pre = keyToNode[key]->pre;
keyToNode[key]->next = *head;
(*head)->pre = keyToNode[key];
keyToNode[key]->pre = NULL;
*head = keyToNode[key];
}
}
};
3、解题2
上一份解题需要对边界进行判断,判断是否是头节点和为节点,简化判断,添加头节点和尾节点
class Solution {
public:
/**
* lru design
* @param operators int整型vector<vector<>> the ops
* @param k int整型 the k
* @return int整型vector
*/
struct Node{
int key;
int val;
Node* pre;
Node* next;
};
map<int,Node*> keyToNode;
vector<int> LRU(vector<vector<int> >& operators, int k) {
// write code here
Node* head = (Node*)malloc(sizeof(Node));
Node* end = (Node*)malloc(sizeof(Node));
head->pre = NULL;
head->next = end;
end->pre = head;
end->next = NULL;
int len = 0;
vector<int> result;
if(operators.size() == 0 || k <= 0)return result;
for(int i = 0;i<operators.size();i++){
if(operators[i][0] == 1){
Set(operators[i][1],operators[i][2],head,end,len,k);
}else{
Get(operators[i][1],head,end,result);
}
}
return result;
}
void Set(int key ,int val,Node* head,Node* end,int &len,int k){
//创建节点
Node* tmp = (Node*)malloc(sizeof(Node));
tmp->key = key;
tmp->val = val;
tmp->next = head->next;
tmp->pre = head;
head->next->pre = tmp;
head->next = tmp;
len++;
//节点处理
if(keyToNode.find(key) == keyToNode.end()){
//删除最后一个节点
if(len>k){
keyToNode.erase(end->pre->key);
end->pre->pre->next = end;
end->pre = end->pre->pre;
len--;
}
keyToNode[key] = tmp;
}else{
keyToNode[key]->pre->next = keyToNode[key]->next;
keyToNode[key]->next->pre = keyToNode[key]->pre;
keyToNode[key] = tmp;
}
return;
}
void Get(int key,Node* head,Node* end,vector<int> &res){
if(keyToNode.find(key) == keyToNode.end()){
res.push_back(-1);
}else{
res.push_back(keyToNode[key]->val);
keyToNode[key]->pre->next = keyToNode[key]->next;
keyToNode[key]->next->pre = keyToNode[key]->pre;
//将该节点插入到头节点之后
keyToNode[key]->pre = head;
keyToNode[key]->next = head->next;
head->next->pre = keyToNode[key];
head->next = keyToNode[key];
}
}
};
4、解题4
go语言编写
package main
/**
* lru design
* @param operators int整型二维数组 the ops
* @param k int整型 the k
* @return int整型一维数组
*/
type Node struct{
Key,Val int
Pre,Next *Node
}
var KeyToNode map[int]*Node
func LRU( operators [][]int , k int ) []int {
// write code here
var res []int
if len(operators) == 0 || k <= 0{
return res
}
KeyToNode = make(map[int]*Node)
//初始化头节点和尾节点
head := &Node{}
end := &Node{}
head.Pre = nil
head.Next = end
end.Pre = head
end.Next = nil
lenth := 0
//操作
for _,val := range operators{
if val[0] == 1{
Set(val[1],val[2],k,head,end,&lenth);
}else{
Get(val[1],head,&res)
}
}
return res;
}
func Get(key int,head *Node,res *[]int){
if val,ok := KeyToNode[key];ok{
*res = append((*res),val.Val)
KeyToNode[key].Pre.Next = KeyToNode[key].Next
KeyToNode[key].Next.Pre = KeyToNode[key].Pre
//该节点放入头节点之后
KeyToNode[key].Pre = head
KeyToNode[key].Next = head.Next
head.Next.Pre = KeyToNode[key]
head.Next = KeyToNode[key]
}else{
(*res) = append((*res),-1)
}
return
}
func Set(key,val,k int,head,end *Node,lenth *int){
//创建节点
tmp := &Node{
Key: key,
Val: val,
}
tmp.Next = head.Next
tmp.Pre = head
head.Next.Pre = tmp
head.Next = tmp
(*lenth)++;
//处理
if _,ok := KeyToNode[key];ok{
KeyToNode[key].Pre.Next = KeyToNode[key].Next
KeyToNode[key].Next.Pre = KeyToNode[key].Pre
KeyToNode[key] = tmp
}else{
if (*lenth) > k{
delete(KeyToNode,end.Pre.Key)
end.Pre.Pre.Next = end
end.Pre = end.Pre.Pre
(*lenth)--;
}
KeyToNode[key] = tmp
}
return
}