请你讲讲LRU算法的实现原理?

  1. LRU算法:LRU算法用于缓存淘汰。思路是将缓存中最近最少使用的对象删除掉
  2. 实现方式:利用链表和hashmap。 当需要插入新的数据项的时候,如果新数据项在链表中存在(一般称为命中),则把该节点移到链 表头部,如果不存在,则新建一个节点,放到链表头部,若缓存满了,则把链表最后一个节点删除 即可。 在访问数据的时候,如果数据项在链表中存在,则把该节点移到链表头部,否则返回-1。这样一来 在链表尾部的节点就是最近最久未访问的数据项。
class LRUCache {
  list<pair<int, int>> cache;//创建双向链表,用于存储缓存的键值对
  unordered_map<int, list<pair<int, int>>::iterator> map;//创建哈希表,用于快速查找缓存的键值对在链表中的位置
  int cap;//缓存的最大容量
public:
  LRUCache(int capacity) {//构造函数,初始化缓存的最大容量
	cap = capacity;
  }
  int get(int key) {//获取指定键对应的值
	if (map.count(key) > 0){//如果哈希表中存在该键,则表示该键对应的值已经缓存过了
	  auto temp = *map[key];//将该键值对从链表中移除,并保存到临时变量中
	  cache.erase(map[key]);//从链表中移除该键值对
	  map.erase(key);//从哈希表中移除该键
	  cache.push_front(temp);//将该键值对插入到链表头部
	  map[key] = cache.begin();//将键映射到链表头部
	  return temp.second;//返回该键对应的值
	}
	return -1;//否则返回-1,表示不存在该键
  }
  void put(int key, int value) {//存储指定键值对
	if (map.count(key) > 0){//如果哈希表中存在该键,则表示该键对应的值已经缓存过了
	  cache.erase(map[key]);//从链表中移除该键值对
	  map.erase(key);//从哈希表中移除该键
	}
	else if (cap == cache.size()){ //如果链表已经达到最大容量,则需要移除最久未使用的键值对
	  auto temp = cache.back();//获取链表尾部的键值对
	  map.erase(temp.first);//从哈希表中移除该键
	  cache.pop_back();//从链表中移除该键值对
	}
	cache.push_front(pair<int, int>(key, value));//将新的键值对插入到链表头部
	map[key] = cache.begin();//将键映射到链表头部
  }
};
/**
* 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);
*/

该代码实现了一个LRU Cache,使用双向链表和哈希表来存储缓存的键值对,并使用LRU(Least Recently Used)算法来淘汰最久未使用的键值对。通过双向链表来维护缓存的顺序,从而实现快速的插入、删除和移动操作;同时,通过哈希表来实现快速的查找操作,从而实现O(1)的时间复杂度。

全部评论

相关推荐

6 52 评论
分享
牛客网
牛客企业服务