LRU实现

动态地维护容量一定的hash表,访问频率高的保留,反之则视剩余容量决定是否保存,

一般的hash表直接记录各个键值对就行了,但多了容量有限的情况,要做一点改动。这里可以通过双端链表来保存键值对,key被访问了就移动到链表头部,对应“访问频率高”的情况,而原本的hash表就不能简单的存储键值对了,此时应该记录链表节点的指针,毕竟链表中已经记录了键值对。为什么用双端链表,因为移动结点方便。

思路厘清了剩余的就是基本的实现了,就是双端链表和hash表的操作

#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;

/*
lru:用空间换时间
双端链表	key/value
unordered_hashmap	key和结点指针
get

set
维护:容量限制
其实储存用hashmap已经够了,key和value,双端链表是为了记录使用频率
*/

struct DNode {
	DNode* pre, * next;
	int key, value;
	DNode(int key = 0, int value = 0) :key(key), value(value), pre(NULL), next(NULL) {}
};

class LRUCache {
	unsigned int capacity;
	unordered_map<int, DNode*>mp;
	DNode* Head, * Tail;		//头尾节点不储存数据
public:
	explicit LRUCache(int a) :capacity(a), Head(new DNode), Tail(new DNode) {
		Head->next = Tail; Tail->pre = Head;
	}
	~LRUCache() {
		DNode* node = Head;
		while (node != Tail) {
			node = node->next;
			delete node->pre;
		}
		delete Tail;
	}
	int get(int k) {
		if (mp.count(k)) {
			MoveDNode2Head(mp[k]);	//mp[k]是指针,通过下标访问
			return mp[k]->value;
		}
		else return -1;
	}
	void MoveDNode2Head(DNode* node) {
		if (!node || node->pre == Head)return;
		removeDNode(node);
		addDNode2Head(node);
	}
	void removeDNode(DNode* node) {
		if (!node)return;
		node->pre->next = node->next;
		node->next->pre = node->pre;
	}
	void addDNode2Head(DNode* node) {
		if (!node || node->pre == Head)return;
		node->next = Head->next;
		Head->next->pre = node;
		Head->next = node;
		node->pre = Head;
	}
	void set(int k, int v) {
		if (!mp.count(k)) {
			DNode* node = new DNode(k, v);
			mp[k] = node;
			addDNode2Head(node);
			if (mp.size() > capacity) {
				DNode* last = Tail->pre;
				mp.erase(last->key);
				removeDNode(last);
				delete last;
			}
		}
		else {
			mp[k]->value = v;
			MoveDNode2Head(mp[k]);
		}
	}
};

class Solution {
public:
    /**
     * lru design
     * @param operators int整型vector<vector<>> the ops
     * @param k int整型 the k
     * @return int整型vector
     */
    vector<int> LRU(vector<vector<int> >& operators, int k) {
        // write code here
        LRUCache lru(k);
        vector<int> res;
        for (auto vec : operators) {
            if (vec[0] == 1) {
                lru.set(vec[1], vec[2]);
            }
            else {
                res.push_back(lru.get(vec[1]));      //只获得get的键值?
            }
        }
        return res;
    }
};

void test() {
	vector<vector<int> > vv = { {1,1,1},{1,2,2},{1,3,2},{2,1},{1,4,4},{2,2} };
	Solution s;
	vector<int> vec = s.LRU(vv, 10);
	for (auto i : vec)cout << i << " " << endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值