Leetcode:LRUCache四个版本实现
2015-01-30 15:17
267 查看
题目
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations:getand
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.
链接:https://oj.leetcode.com/problems/lru-cache/
分析
1:维护最近最少(LRU)使用的cache1)使用count计数,每次操作cache时(get、set),该cache的count置0,其余cache的count加1,count最大的为最近最少使用的cache
2)使用链表,每次操作cache时(get、set),将该cache移动至链表头,链表尾的cache为最近最少使用的cache
2:快速查找cache
1)使用stl::unordered_map存储cache地址(内部hashTable)
版本一
使用std::list维护LRU,链表中存储cache实际空间。
Runtime: 248ms。
struct BiListNode { BiListNode() {}; BiListNode(int key, int value):key(key), value(value) {}; int key; int value; BiListNode* pre; BiListNode* next; }; class BiList { public: BiList():_count(0) { _head = new BiListNode(); _head->pre = _head; _head->next = _head; } void push_front(BiListNode* pNode); void move_front(BiListNode* pNode); BiListNode* begin() { return _head->next; } BiListNode* rbegin() { return _head->pre; } void pop_back(); int size() { return _count; } ~BiList(); private: BiListNode* _head; int _count; }; void BiList::push_front(BiListNode* pNode) { pNode->next = _head->next; pNode->pre = _head; _head->next->pre = pNode; _head->next = pNode; if (_head->pre == _head) { _head->pre = pNode; } ++_count; } void BiList::move_front(BiListNode* pNode) { if (pNode == _head->next) { return; } pNode->pre->next = pNode->next; pNode->next->pre = pNode->pre; pNode->next = _head->next; pNode->pre = _head; _head->next->pre = pNode; _head->next = pNode; } void BiList::pop_back() { BiListNode* tailPtr = _head->pre; tailPtr->pre->next = _head; _head->pre = tailPtr->pre; delete tailPtr; --_count; } BiList::~BiList() { for (BiListNode* itr = _head->next; itr != _head; itr = itr->next) { delete itr; } delete _head; } struct hashNode { hashNode(int key, BiListNode* ptr):key(key), ptr(ptr), next(NULL) {}; int key; BiListNode* ptr; hashNode* next; }; class HashTable { public: HashTable(int capacity); hashNode* find(int key); void insert(int key, BiListNode* ptr); void erase(int key); ~HashTable(); private: int _capacity; hashNode** hashArray; }; HashTable::HashTable(int capacity):_capacity(capacity) { hashArray = new hashNode*[capacity]; for (int i = 0; i < _capacity; ++i) { hashArray[i] = NULL; } } hashNode* HashTable::find(int key) { for (hashNode* itr = hashArray[key % _capacity]; itr != NULL; itr = itr->next) { if (itr->key == key) { return itr; } } return NULL; } void HashTable::insert(int key, BiListNode* ptr) { hashNode* tmp = new hashNode(key, ptr); int relativeKey = key % _capacity; if (hashArray[relativeKey] == NULL) { hashArray[relativeKey] = tmp; return; } tmp->next = hashArray[relativeKey]; hashArray[relativeKey] = tmp; } void HashTable::erase(int key) { for (hashNode* pre = hashArray[key % _capacity], *itr = pre; itr != NULL; pre = itr, itr = itr->next) { if (itr->key == key) { if (itr != pre) pre->next = itr->next; else // head hashArray[key % _capacity] = itr->next; delete itr; } } } HashTable::~HashTable() { for (int i = 0; i < _capacity; ++i) { for (hashNode* itr = hashArray[i]; itr != NULL;) { hashNode* tmp = itr; itr = itr->next; delete tmp; } } delete [] hashArray; } class LRUCache { public: LRUCache(int capacity):_capacity(capacity) { hashTable = new HashTable(1024); }; int get(int key); void set(int key, int value); ~LRUCache() { delete hashTable; } private: int _capacity; BiList bilist; HashTable* hashTable; }; int LRUCache::get(int key) { hashNode* tmp = hashTable->find(key); if (tmp != NULL) { bilist.move_front(tmp->ptr); return tmp->ptr->value; } return -1; } void LRUCache::set(int key, int value) { hashNode* tmp = hashTable->find(key); if (tmp != NULL) { // set bilist.move_front(tmp->ptr); tmp->ptr->value = value; return; } // insert if (bilist.size() == _capacity) { hashTable->erase((bilist.rbegin())->key); bilist.pop_back(); } bilist.push_front(new BiListNode(key, value)); hashTable->insert(key, bilist.begin()); }
View Code
开链哈希表72行代码
相关文章推荐
- leetcode:Copy List with Random Pointer 细致分析,以及代码实现(JAVA版本)
- 巧用DBGrid控件的Sort属性实现“点击标题栏自动排序功能”。(改进版本)
- 分析模式-计量的C++实现——完美版本
- .NET中多语言版本的实现---WebForm
- 实现uc版本维护功能,基线baseline的实现也就容易了
- asp.net2.0多语言版本网站软件的实现--青蛙非王子(lostfrog)
- 修正了版本管理实现中的一个bug
- .NET中多语言版本的实现---WinForm
- [最后版本]利用TWAIN-实现与图像输入设备的通讯--孙涛--
- 今天得知FastReport从1.9版本开始对PDF输出增加了我所实现的CJK支持
- VSS实现版本控制管理的一些使用方法
- vb多国语言版本的实现
- 用VC++实现版本在线升级
- 策略(Strategy)模式(C#实现版本)
- 用控件仅一条指令实现界面换肤和多语言版本(YFSkins)
- Windows 2000 四个版本的区别
- 软件的版本更新检查实现
- MSDN关于.net 2.0 beta 版本中范型实现的介绍
- 结合Mantis缺陷管理系统实现vss的版本管理
- IE5实现高版本的String.prototype.replace功能