题目:
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.
这是我的代码:
1 class LRUCache{ 2 public: 3 int num; 4 int max; 5 list<int> latest_key; //用于保存使用情况,队头是最久未使用的,队尾是最近使用的 6 unordered_map<int, int> cache; //用于保存key,value 7 8 LRUCache(int capacity) { 9 num = 0; 10 max = capacity; 11 } 12 13 int get(int key) { 14 unordered_map<int, int>::iterator it = cache.find(key); 15 list<int>::iterator iter; 16 if (it == cache.end()) //如果没有找到key 17 return -1; 18 else //如果找到了key,就在对应的最近latest队列里面修改key的位置,先把key所在的位置删除,再把key放到队尾 19 { 20 iter = latest_key.begin(); 21 while (*iter != key) 22 iter++; 23 latest_key.erase(iter); 24 latest_key.push_back(key); 25 return it->second; 26 } 27 } 28 29 void set(int key, int value) { 30 unordered_map<int, int>::iterator it = cache.find(key); 31 list<int>::iterator iter; 32 if (it != cache.end()) //如果要插入的已经有key存在,就先在优先队列里面找到key出现的位置,删除,再把key插入队尾 33 { 34 it->second = value; 35 iter = latest_key.begin(); 36 while (*iter != key) 37 iter++; 38 latest_key.erase(iter); 39 latest_key.push_back(key); 40 } 41 else //如果要插入的不存在 42 { 43 if (num<max) //如果不超过cache容量,则直接在cahe中插入,再在队尾添加该key 44 { 45 num++; 46 cache.insert(std::pair< int, int >(key, value)); 47 latest_key.push_back(key); 48 } 49 else //如果cache已经满了,则根据队头元素,在cache删除对应键值,再在队列中删除这个队头,之后,把新要插入的键值插入cache中,把新key插入队尾 50 { 51 int latest = latest_key.front(); 52 cache.erase(latest); 53 latest_key.pop_front(); 54 cache.insert(std::pair< int, int >(key, value)); 55 latest_key.push_back(key); 56 } 57 } 58 } 59 };
当我把代码中出现:
1 iter = latest_key.begin(); 2 while (*iter != key) 3 iter++;
部分替换为:
1 iter=find(latest_key.begin(),latest_key.end(),key);
就会报错:
Time Limit Exceeded
Last executed input: 2048,[set(1178,3401),set(903,6060).....
我大致查了一下find的实现机制,也是遍历啊,按理说这两者效率差不多,为什么替换之后就不能通过?而替换之前能通过,求大神解答!!
万分感谢!!!
在Leetcode上问,已经得到答案:
之前的那个算法效率确实不高,压线过的,修改了原有代码,增加了一个unordered_map<int, list<int>iterator>用来索引list,可以使时间复杂度降到O(1):
1 class LRUCache{ 2 private: 3 unordered_map<int, int> cache; 4 unordered_map<int, list<int>::iterator> find_key; 5 list<int> latest_key; 6 int max; 7 public: 8 LRUCache(int capacity) : max(capacity){ 9 10 } 11 12 int get(int key) { 13 if (cache.find(key) == cache.end()){ 14 return -1; 15 } 16 latest_key.erase(find_key[key]); 17 latest_key.push_front(key); 18 find_key[key] = latest_key.begin(); 19 return cache[key]; 20 } 21 22 void set(int key, int value) { 23 if (cache.find(key) == cache.end()) { 24 if (cache.size() >= max) { 25 cache.erase(latest_key.back()); 26 latest_key.pop_back(); 27 cache[key] = value; 28 latest_key.push_front(key); 29 find_key[key] = latest_key.begin(); 30 } 31 else { 32 cache[key] = value; 33 latest_key.push_front(key); 34 find_key[key] = latest_key.begin(); 35 } 36 } 37 else { 38 cache[key] = value; 39 latest_key.erase(find_key[key]); 40 latest_key.push_front(key); 41 find_key[key] = latest_key.begin(); 42 } 43 } 44 };