題目來源
題目的意思就是說給定大小固定的空間,然后要實現(xiàn)get,put操作,假如容量滿了,那么根據(jù)最近最少使用原則來進(jìn)行刪除,兩個操作都用O(1)的時間完成。
這道題我在之前京東面試的時候碰到了,然后當(dāng)時想了挺久,沒想出來。
看了看討論區(qū),實際上也不是很難,總的想法和我原來想的差不多,不過我對那些基本數(shù)據(jù)結(jié)構(gòu)的了解不夠透徹。
實際上就是需要一個哈希表以及一個雙鏈表,哈希表中key存的是就是key,value存的是雙鏈表的iterator,指向雙鏈表中存放對應(yīng)key的位置。
然后雙鏈表中存放值。
get操作,因為哈希表,所以是O(1)的,get操作后需要將對應(yīng)節(jié)點移到隊首。
然后復(fù)雜一點是put操作,首先需要考慮這個key在雙鏈表中是否已經(jīng)存在,存在的話就把雙鏈表的那個節(jié)點移到隊首來。假如不存在,首先需要判斷容量是否已滿,假如已經(jīng)滿了,就把隊尾刪掉。假如不滿,那么直接往隊首插入一個值即可。
其中比較復(fù)雜的操作實際上就是這個雙鏈表怎么移動,怎么把某個元素移到隊首,寫起來比較復(fù)雜。但是!STL已經(jīng)把你做好了,用splice操作直接來實現(xiàn)。
代碼如下:
class LRUCache {
public:
LRUCache(int capacity) : m_capacity(capacity) {}
int get(int key) {
auto found_iter = m_map.find(key);
if (found_iter == m_map.end())
return -1;
m_list.splice(m_list.begin(), m_list, found_iter->second);
return found_iter->second->second;
}
void put(int key, int value) {
auto found_iter = m_map.find(key);
if (found_iter != m_map.end()) {
found_iter->second->second = value;
m_list.splice(m_list.begin(), m_list, found_iter->second);
return;
}
if (m_map.size() == m_capacity) {
int del_key = m_list.back().first;
m_list.pop_back();
m_map.erase(del_key);
}
m_list.emplace_front(key, value);
m_map[key] = m_list.begin();
}
private:
size_t m_capacity;
unordered_map<int, list<pair<int, int>>::iterator> m_map;
list<pair<int, int>> m_list;
};
/**
* 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);
*/