【数据结构】LRU缓存的简单模拟实现(leetcode力扣146LRU缓存)


一、定义

LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。
Cache的容量有限,因此当Cache的容量用完后,而又有新的内容需要添加进来时, 就需要挑选并舍弃原有的部分内容,从而腾出空间来放新内容。LRU Cache 的替换原则就是将最近最少使用的内容替换掉。

二、LRU模拟实现

146.LRU缓存
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

下面我们就借力扣的这道题来简单实现一个

题目中要求我们以O(1)的时间复杂度来完成,查找的话我们首先肯定会想到哈希表,但又涉及一个问题,我们查找完之后还需要更新一下刚刚查找数据的位置,将这个数据置为是新的数据,我们如何解决查找完改变数据的标识也做到O(1)呢?

要保持高效实现O(1)的put和get,那么使用双向链表和
哈希表的搭配是最高效和经典的
。使用双向链表是因为双向链表可以实现任意位置O(1)的插入和删除,使用哈希表是因为哈希表的增删查改也是O(1)。
在这里插入图片描述

需要注意:这里最巧的设计就是将unordered_map的value type放成list<pair<int, int>>::iterator,因为这样,当get一个已有的值以后,就可以直接找到key在list中对应的iterator,然后将这个值移动到链表的头部,保持LRU。

二、代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<list>
#include<unordered_map>

using namespace std;


class LRUCache {
   

public:
	LRUCache(int capacity)
		:_capacity(capacity)
	{
   }

	int get(int key) {
   
		
		auto ret = _hashMap.find(key);
		//在hash中找到了key存的地方
		if (ret != _hashMap.end()) {
   
			LtIter it = ret->second;

			//将it移动到_LRUList的头部
			_LRUList.splice(_LRUList.begin(), _LRUList, it);
			return it->second;
		}
		else {
   
			return -1;
		}
	}

	void put(int key, int value) {
   
		auto ret = _hashMap.find(key);

		//原来没有key的数据则添加
		if (ret == _hashMap.end()) {
   

			//LRU满了,删除最近最少使用的就是链表尾部
			if (_capacity == _hashMap.size()) {
   
				pair<int, int>back = _LRUList.back();

				_hashMap.erase(back.first);//删哈希里面
				//链表里面k存的和哈希的是同一个key
				_LRUList.pop_back();//删链表尾部
			}
			//放入新的数据到链表头部
			_LRUList.push_front(make_pair(key, value));
			//哈希表中添加
			_hashMap[key] = _LRUList.begin();
		}

		//原来有key的数据则更新
		else {
   
			LtIter it = ret->second;
			it->second = value;
			//将这个位置移到链表头部
			_LRUList.splice(_LRUList.begin(), _LRUList, it);
		}
	}

private:
	//链表存kv结构
	//k为key值,v为我们要更新的数据
	typedef list<pair<int, int>>::iterator LtIter;//重命名链表迭代器

	int _capacity; // 容量大小,超过容量则换出,保持LRU
	//_LRUList假设链表头部为最近使用的,尾部为最近最少使用
	list<pair<int, int>> _LRUList;
	//hash中存放的是key值与对应链表迭代器的的映射关系
	unordered_map<int, LtIter>_hashMap;
 };

相关推荐

  1. Leetcode 146. LRU 缓存

    2023-12-25 23:24:04       22 阅读
  2. ---***********LRU 缓存***********

    2023-12-25 23:24:04       183 阅读
  3. 100】146.LRU缓存

    2023-12-25 23:24:04       70 阅读
  4. 记录)146. LRU 缓存

    2023-12-25 23:24:04       56 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-25 23:24:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-25 23:24:04       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-25 23:24:04       82 阅读
  4. Python语言-面向对象

    2023-12-25 23:24:04       91 阅读

热门阅读

  1. arm day6

    2023-12-25 23:24:04       60 阅读
  2. 爬虫抓取链家二手房数据

    2023-12-25 23:24:04       49 阅读
  3. date工具类

    2023-12-25 23:24:04       52 阅读
  4. C语言中switch语句中的case后()

    2023-12-25 23:24:04       59 阅读
  5. [运维|shell] 编写shell脚本定期清理日志

    2023-12-25 23:24:04       56 阅读
  6. 第6章1-字符串及正则表达式 p63

    2023-12-25 23:24:04       51 阅读
  7. 避免约束系数过大的2种技巧

    2023-12-25 23:24:04       58 阅读
  8. ubuntu22.04上安装charles-proxy

    2023-12-25 23:24:04       53 阅读
  9. GO语言基础笔记(四):并发编程基础

    2023-12-25 23:24:04       50 阅读
  10. 第六章 卷:将磁盘挂载到容器

    2023-12-25 23:24:04       49 阅读