LeetCode 146. LRU Cache(map+vector,C++,速度较慢待优化)

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

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(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.

Follow up:
Could you do both operations in O(1) time complexity?

Example:

LRUCache cache = new LRUCache( 2 /* capacity */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // returns 1
cache.put(3, 3);    // evicts key 2
cache.get(2);       // returns -1 (not found)
cache.put(4, 4);    // evicts key 1
cache.get(1);       // returns -1 (not found)
cache.get(3);       // returns 3
cache.get(4);       // returns 4

思路:这题其实就是实现操作系统中的LRU置换算法。LRU算法的含义是当内存中页面满了(这题中就是容量满了),置换页面时,需要将原先存在的页面置换出来,而置换出的页面是最久没有被访问过的页面

这题我采用一个vector(因为需要删除map中的key,value对,所以存储的是key)模拟一个队列,vector根据时间顺序来排序,最近访问过的页面在vector的最后,而最久没有访问过的页面在vector的第一个元素,每次put新的如果页面(vector)满了则需要将key == vecrtor[0]的键值对删除,同时在vector的最后插入新加入的页面(key),每次get操作后也要更新vector。具体的细节见代码和注释。

C++ map+vector

class LRUCache {
public:
	unordered_map<int, int> dic;
    vector<int> time;//最近加入或者最近使用过的key放在最后
    int c;
    
    LRUCache(int capacity) {
        c = capacity;
    }
    
    int get(int key) {
        unordered_map<int, int>::iterator iter = dic.find(key);
        if(iter == dic.end())
            return -1;//not found
        else{
            vector<int>::iterator it = std::find(time.begin(), time.end(), key);
            time.erase(it);//访问过的元素放到末尾
            time.push_back(key);
            return iter->second;//value
        }
    }
    
    void put(int key, int value) {
        if(dic.count(key))//key 已经存在cache中
        {
            dic[key] = value;//key设为新的value
            vector<int>::iterator it = std::find(time.begin(), time.end(), key);
            time.erase(it);//更新key的使用时间
            time.push_back(key);
        }
        else{//key不在cache中
            if(time.size()==c){//cache满了,先删除一个最近最久没有使用的元素
                int pop = time[0];
                time.erase(time.begin());//删除最久没有使用的元素,放在time的开头
                dic.erase(pop);
            }
            time.push_back(key);
            dic[key] = value;
        }
    }
};

/**
 * 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);
 */

结果
速度比较慢,然后我想制约这个速度的应该是vector的删除操作?因为在连续存储的顺序表中删除中间一个元素可能需要移动后面的元素?不知道vector是不是这样实现的,然后我把vector换成list,竟然速度更慢了?有点迷,所以拖了几天才写博客,但是现在还不是很清楚,看了评论区,大部分人都是自己实现双向链表来实现删除才能达到很高的效率,先留个坑,以后填吧。。。
在这里插入图片描述

你可能感兴趣的:(刷题,Leetcode)