zoukankan      html  css  js  c++  java
  • LeetCode: LRU Cache [146]

    【题目】

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

    get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
    set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.


    【题意】

            实现LRU策略

            1. 依据key取value

            2. 插入key-value时,须要删除LRU的item


    【思路】

            维护一个Map记录相应的<key, value>对
            为了模拟key的訪问先后关系,须要维护一个訪问次序列表,越靠后的节点,訪问时间距当前时间越短
    而在insert或者訪问key的时候,须要从列表中找到相应的key,并把它调整到列表为。
    这里遇到两个问题,一个是查找,还有一个是移动到末尾

    假设使用顺序表,查找O(n),移动O(n),在cache规模非常大时时间代价过高
    因此这里使用双向链表来处理


    【代码】

    struct Node{
        int key;
        int val;
        Node*prev;
        Node*next;
        Node(int k, int v): key(k), val(v){
            prev=NULL; next=NULL;
        }
    };
    
    class LRUCache{
    private:
    	Node* head;
    	Node* tail;
    	int capacity;
    	map<int, Node*>cache;
    public:
        LRUCache(int capacity) {
            this->head = NULL;
    		this->tail = NULL;
    		this->capacity = capacity;
        }
    	
    	void move2tail(Node* node){
    		if(node==tail)return;
    		if(node==head){
    			head = node->next;
    			head->prev=NULL;
    			tail->next=node;
    			node->prev=tail;
    			tail=node;
    			tail->next=NULL;
    		}
    		else{
    			node->prev->next = node->next;
    			node->next->prev = node->prev;
    			tail->next=node;
    			node->prev=tail;
    			tail=node;
    			tail->next=NULL;
    		}
    	}
        
        int get(int key) {
            if(this->cache.find(key)==this->cache.end())return -1;
    		move2tail(this->cache[key]);
    		return this->cache[key]->val;
        }
        
        void set(int key, int value) {
            if(this->cache.find(key)==this->cache.end()){//cache中还没有
    			if(this->capacity==0){//cache已经满了
    				//删除头结点
    				this->cache.erase(head->key);
    				head=head->next;
    				if(head)head->prev=NULL;
    				else tail=NULL;
    			}
    			else{//cache还没满
    				this->capacity--;
    			}
    			//加入新节点
    			Node* newNode=new Node(key, value);
    			this->cache[key]=newNode;
    			if(tail){
    				tail->next=newNode;
    				newNode->prev=tail;
    				tail=newNode;
    				tail->next=NULL;
    			}
    			else{
    				head=tail=newNode;
    			}
    		}
    		else{//cache中已经有了
    			this->cache[key]->val = value;
    			move2tail(this->cache[key]);
    		}
        }
    };


  • 相关阅读:
    批量SSH操作工具---OmniTTY安装
    CentOS6.6修改主机名和网络信息
    浪潮服务器通过ipmitool获取mac地址
    linux批量执行工具omnitty使用方法
    操作系统下查看HBA卡信息wwn的方法
    Linux下multipath多路径配置
    IPMITOOL 配置BMC用户设置
    第五讲 对于耦合的认识 target/action设计模式 delegate设计模式 手势识别器
    UI第四讲.事件处理(按钮点击切换视图,触摸事件)
    UI第三讲.自定义视图 视图控制器 检测屏幕旋转
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3890809.html
Copyright © 2011-2022 走看看