leetcode146——LRU缓存机制

题目地址

LRU(Least Recently Used)是一种常见的页面置换算法,在计算中,所有的文件操作都要放在内存中进行,然而计算机内存大小是固定的,所以我们不可能把所有的文件都加载到内存,因此我们需要制定一种策略对加入到内存中的文件进项选择。

在这里插入图片描述

一、hash+双向链表

我们使用一个哈希表来维护,值和链表节点关系。用一个双向链表来模拟LRU缓存,该双向链表需要以下几个功能:

  • 删除尾部节点(代表最久未使用的数据)
  • 插入一个节点到头部位置(新使用了一个数据值)
  • 移动一个节点到首部(使用过的数据再次使用)
struct DLinkedNode
{
	int key, value;
	DLinkedNode* pre;
	DLinkedNode* nex;
	DLinkedNode() :key(0), value(0), pre(nullptr), nex(nullptr) {};
	DLinkedNode(int _key,int _value) :key(_key), value(_value), pre(nullptr), nex(nullptr) {};
};
class LRUCache {
	unordered_map<int, DLinkedNode*> cache;
	DLinkedNode* head;
	DLinkedNode* tail;
	int size;//目前缓存中的数据数量
	int v;//最大容量
private:
	void add_to_head(DLinkedNode* node)
	{
		node->pre = head;
		node->nex = head->nex;
		head->nex->pre = node;
		head->nex = node;
	}
	void removenode(DLinkedNode* node)//移除节点
	{
		node->pre->nex = node->nex;
		node->nex->pre = node->pre;
	}
	void movehead(DLinkedNode* node)
	{//移动到头部
		removenode(node);
		add_to_head(node);
	}
	int  remove_tail()
	{
		DLinkedNode* tail_node;
		tail_node = tail->pre;
		tail_node->pre->nex = tail;
		tail->pre = tail_node->pre;
		int key = tail_node->key;
		delete tail_node;
		return key;
	}
public:
	LRUCache(int capacity) {
		size = 0;
        v=capacity;
		head = new DLinkedNode();
		tail = new DLinkedNode();
		head->nex = tail;
		tail->pre = head;
	}

	int get(int key) {
		if (!cache.count(key))
		{
			return -1;
		}
		DLinkedNode* node = cache[key];
		movehead(node);
		return node->value;
	}

	void put(int key, int value) {
		if (!cache.count(key))
		{
			DLinkedNode* node = new DLinkedNode(key, value);
			add_to_head(node);
			cache[key] = node;
			size++;
			if (size > v)
			{
				int key=remove_tail();
				cache.erase(key);
                size--;
			}
		}
		else
		{
			DLinkedNode* node = cache[key];
			node->value = value;
			movehead(node);
		}
	}
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法是一种字符串匹配算法,用于在一个文本串S内查找一个模式串P的出现位置。它的时间复杂度为O(n+m),其中n为文本串的长度,m为模式串的长度。 KMP算法的核心思想是利用已知信息来避免不必要的字符比较。具体来说,它维护一个next数组,其中next[i]表示当第i个字符匹配失败时,下一次匹配应该从模式串的第next[i]个字符开始。 我们可以通过一个简单的例子来理解KMP算法的思想。假设文本串为S="ababababca",模式串为P="abababca",我们想要在S中查找P的出现位置。 首先,我们可以将P的每个前缀和后缀进行比较,得到next数组: | i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | --- | - | - | - | - | - | - | - | - | | P | a | b | a | b | a | b | c | a | | next| 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 接下来,我们从S的第一个字符开始匹配P。当S的第七个字符和P的第七个字符匹配失败时,我们可以利用next[6]=4,将P向右移动4个字符,使得P的第五个字符与S的第七个字符对齐。此时,我们可以发现P的前五个字符和S的前五个字符已经匹配成功了。因此,我们可以继续从S的第六个字符开始匹配P。 当S的第十个字符和P的第八个字符匹配失败时,我们可以利用next[7]=1,将P向右移动一个字符,使得P的第一个字符和S的第十个字符对齐。此时,我们可以发现P的前一个字符和S的第十个字符已经匹配成功了。因此,我们可以继续从S的第十一个字符开始匹配P。 最终,我们可以发现P出现在S的第二个位置。 下面是KMP算法的C++代码实现:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值