LeetCode 146 LRU Cache

4702 ワード

テーマ:
メモリ管理におけるLRU(Least Recently Used)メモリ管理アルゴリズムの実現
メモリ管理アルゴリズムではLRUとLFUが異なり、LRUは最も長く使われていないページを削除します
LFUは最近の使用回数が最も少ないページを削除します
大まかな考え方:
この問題は、メモリ管理の復習をしたところです.
まず、各メモリブロックが使用されている場合、1つのメモリブロックが最近使用されているが、他のブロックの相対的な位置は変わらないため、チェーンテーブルで表すことを考慮し、ここでは双方向チェーンテーブルを使用し、チェーンテーブルは最初からノードを最後にし、最近使用されているほど、つまり最後のノードは最近アクセスされ、容量がいっぱいになったとき、ヘッダノードを削除し、空間を空け、ノードの挿入と移動の複雑さはO(1)である.
setの場合key対応valueを検索する必要があるためmapでメンテナンスを行うことを考慮し,mapで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;
        }
    }
};