LeetCode 146 LRU Cache

题目大意:

就是实现内存管理中的LRU(Least Recently Used)内存管理算法

内存管理算法的话,LRU和LFU不同,LRU是移除最久没有使用的页

而LFU是移除最近使用次数最少的页


大致思路:

这个问题的话,表示刚好复习了一下内存管理...

首先由于每个内存块在被使用时,会导致一个内存块最近被使用,而其他的块的相对位置不变,考虑用链表来表示他们,这里使用双向链表,链表从头节点往结尾,越是最近使用,也就是说尾节点是最近访问的,当容量满的时候,删除头节点,腾出空间,插入和移动节点的复杂度是O(1)

当set的时候由于需要查找key对应的value, 考虑用map来进行维护,用map<int, listNode* > 来在O(logn)的时间复杂度内找到对应的节点位置

那么查找节点是否在内存池中的复杂度也就是O(logn),整体的单词操作的时间复杂度是O(logn)


代码如下:

Result  :  Accepted     Time  :  96 ms

/*
 * Author: Gatevin
 * Created Time:  2016/3/7 11:06:11
 * File Name: test.cpp
 */
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
typedef long long lint;

class LRUCache{
private:
    struct listNode{
        listNode* next;
        listNode* prev;
        int key;
        int value;
        listNode(){
            next = NULL;
            prev = NULL;
            key = -1;
            value = 0;
        }
    };

    int lruCapacity;
    int curCapacityUsed;
    listNode* p_Head;
    listNode* p_Tail;
    map<int, listNode*> M;//查找某个key值有没有出现过
    
public:
    LRUCache(int capacity) {
        if(capacity <= 0) puts("Error, capacity should be at least 1");
        p_Head = NULL;
        p_Tail = NULL;
        lruCapacity = capacity;
        curCapacityUsed = 0;
        M.clear();
    }
    
    void moveToTail(listNode* now){
        if(now->next == NULL)//本来就是末尾节点
            return;
        else{
            if(now->prev == NULL){//头节点
                p_Head->next->prev = NULL;
                p_Head = p_Head->next;
                now->next = NULL;
                now->prev = p_Tail;
                p_Tail->next = now;
                p_Tail = now;
                return;
            }else{//中间节点
                now->prev->next = now->next;
                now->next->prev = now->prev;
                p_Tail->next = now;
                now->prev = p_Tail;
                now->next = NULL;
                p_Tail = now;
                return;
            }
        }
    }
    
    int get(int key) {
        map<int, listNode*> :: iterator it = M.find(key);
        if(it == M.end())//Not found
            return -1;
        else{//查找到了,将这个结点移动到链表最后面
            moveToTail(it->second);
            return it->second->value;
        }
    }
    
    void set(int key, int value) {
        map<int, listNode*> :: iterator it = M.find(key);
        if(it == M.end()){//Not found
            if(p_Head == NULL){//链表为空
                p_Head = new listNode();
                p_Head->key = key;
                p_Head->value = value;
                p_Tail = p_Head;
                M[key] = p_Head;
                curCapacityUsed++;
                return;
            }else{//链表不为空,添加新节点到链表末尾
                if(curCapacityUsed == lruCapacity){//已满,需要删除头节点再插入
                    if(p_Head->next == NULL){
                        M.erase(p_Head->key);
                        delete p_Head;
                        p_Head = NULL;
                        p_Tail = NULL;
                        curCapacityUsed--;
                    }else{
                        M.erase(p_Head->key);
                        p_Head = p_Head->next;
                        delete p_Head->prev;
                        p_Head->prev = NULL;
                        curCapacityUsed--;
                    }
                }
                //接下来在末尾插入新节点
                listNode* newTail = new listNode();
                newTail->value = value;
                newTail->key = key;
                if(p_Tail == NULL){
                    p_Head = newTail;
                    p_Tail = p_Head;
                }else{
                    p_Tail->next = newTail;
                    newTail->prev = p_Tail;
                    p_Tail = newTail;
                }
                M[key] = p_Tail;
                curCapacityUsed++;
            }
        }else{
            moveToTail(it->second);
            it->second->value = value;
            return;
        }
    }
};


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值