模拟

双向链表LRU 缓存

  1. class Solution {
  2. list<pair<int, int>> mCache;
  3. int mCapacity;
  4. public:
  5. Solution(int capacity):mCapacity(capacity){
  6. // write code here
  7. }
  8. int get(int key) {
  9. // write code here
  10. auto iter=mCache.begin();
  11. for(;iter!=mCache.end();++iter){
  12. if(iter->first==key){
  13. break;
  14. }
  15. }
  16. if (iter==mCache.end()) return -1;
  17. auto temp = *iter;
  18. mCache.erase(iter);
  19. mCache.emplace_front(temp);
  20. return temp.second;
  21. }
  22. void set(int key, int value){
  23. // write code here
  24. auto iter=mCache.begin();
  25. for(;iter!=mCache.end();++iter){
  26. if(iter->first==key){
  27. break;
  28. }
  29. }
  30. if (iter!=mCache.end()) mCache.erase(iter);
  31. if(mCache.size()==mCapacity){
  32. auto iter = --mCache.end();
  33. mCache.erase(iter);
  34. }
  35. mCache.emplace_front(make_pair(key, value));
  36. }
  37. };

本实现存在的问题:

  1. 链表对于键的查找开销相当大,因为比起连续地址的数组和 vector类型,链表在访问的时候多一个指针的递归,在底层上内存访问也可能回慢一点;

    待优化部分

    于是利用 哈希表来对键值查询的过程做优化 也即是优化如下代码块:

    1. auto iter=mCache.begin();
    2. for(;iter!=mCache.end();++iter){
    3. if(iter->first==key){
    4. break;
    5. }
    6. }

    哈希表 双向链表 LRU 缓存

    整体代码如下:

    1. class Solution {
    2. list<pair<int, int>> mCache;
    3. unordered_map<int, list<pair<int,int>>::iterator> mp;
    4. int mCapacity;
    5. public:
    6. Solution(int capacity):mCapacity(capacity){
    7. // write code here
    8. }
    9. int get(int key) {
    10. // write code here
    11. if(mp.find(key)!=mp.end()){
    12. int value = mp[key]->second;
    13. mCache.erase(mp[key]);
    14. mCache.emplace_front(make_pair(key, value));
    15. mp[key] = mCache.begin();
    16. return value;
    17. }else return -1;
    18. }
    19. void set(int key, int value){
    20. // write code here
    21. if(mp.find(key)!=mp.end()) // 链表中存在键删除后重新插入;
    22. mCache.erase(mp[key]);
    23. else if(mCache.size()==mCapacity){ // 不存在键同时链表满容量;
    24. mp.erase(mCache.back().first);
    25. mCache.pop_back();
    26. }
    27. // 插入键值对到表头;
    28. mCache.emplace_front(make_pair(key, value));
    29. mp[key] = mCache.begin();
    30. }
    31. };

优化性能

image.png
可以看出结果很好;其实第二种方法做的时候没想到,是我看评论区被别人的方法启发的做出来的;

日期