【牛客 - NC93】设计LRU缓存结构(模拟)
設(shè)計(jì)LRU緩存結(jié)構(gòu)_牛客題霸_牛客網(wǎng)
描述
設(shè)計(jì)LRU(最近最少使用)緩存結(jié)構(gòu),該結(jié)構(gòu)在構(gòu)造時(shí)確定大小,假設(shè)大小為 k ,并有如下兩個(gè)功能
1. set(key, value):將記錄(key, value)插入該結(jié)構(gòu)
2. get(key):返回key對(duì)應(yīng)的value值
提示:
1.某個(gè)key的set或get操作一旦發(fā)生,認(rèn)為這個(gè)key的記錄成了最常使用的,然后都會(huì)刷新緩存。
2.當(dāng)緩存的大小超過(guò)k時(shí),移除最不經(jīng)常使用的記錄。
3.輸入一個(gè)二維數(shù)組與k,二維數(shù)組每一維有2個(gè)或者3個(gè)數(shù)字,第1個(gè)數(shù)字為opt,第2,3個(gè)數(shù)字為key,value
若opt=1,接下來(lái)兩個(gè)整數(shù)key,?value,表示set(key,?value)
若opt=2,接下來(lái)一個(gè)整數(shù)key,表示get(key),若key未出現(xiàn)過(guò)或已被移除,則返回-1
對(duì)于每個(gè)opt=2,輸出一個(gè)答案
4.為了方便區(qū)分緩存里key與value,下面說(shuō)明的緩存里key用""號(hào)包裹
要求:set和get操作復(fù)雜度均為?O(1)
示例1
輸入:
[[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]],3復(fù)制返回值:
[1,-1]復(fù)制說(shuō)明:
[1,1,1],第一個(gè)1表示opt=1,要set(1,1),即將(1,1)插入緩存,緩存是{"1"=1} [1,2,2],第一個(gè)1表示opt=1,要set(2,2),即將(2,2)插入緩存,緩存是{"1"=1,"2"=2} [1,3,2],第一個(gè)1表示opt=1,要set(3,2),即將(3,2)插入緩存,緩存是{"1"=1,"2"=2,"3"=2} [2,1],第一個(gè)2表示opt=2,要get(1),返回是[1],因?yàn)間et(1)操作,緩存更新,緩存是{"2"=2,"3"=2,"1"=1} [1,4,4],第一個(gè)1表示opt=1,要set(4,4),即將(4,4)插入緩存,但是緩存已經(jīng)達(dá)到最大容量3,移除最不經(jīng)常使用的{"2"=2},插入{"4"=4},緩存是{"3"=2,"1"=1,"4"=4} [2,2],第一個(gè)2表示opt=2,要get(2),查找不到,返回是[1,-1]示例2
輸入:
[[1,1,1],[1,2,2],[2,1],[1,3,3],[2,2],[1,4,4],[2,1],[2,3],[2,4]],2復(fù)制返回值:
[1,-1,-1,3,4]復(fù)制
備注:
1≤K≤N≤105 ?2×109≤x,y≤2×109解題報(bào)告:
首先設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)使用hash表+鏈表實(shí)現(xiàn)。
首先用鏈表來(lái)實(shí)現(xiàn)頁(yè)面緩存。用hash表來(lái)快速定位每個(gè)key對(duì)應(yīng)的value是什么。方便進(jìn)行g(shù)et操作。
AC代碼:
優(yōu)化后較為簡(jiǎn)單的代碼:
即我們調(diào)用層,代碼十分清晰。具體實(shí)現(xiàn)層,實(shí)現(xiàn)了鏈表層面的insert和remove,順便更新下key就可以了。
注意點(diǎn)1:remove函數(shù)里面的k_pos.erase操作要放到if內(nèi),不然已經(jīng)return了就不會(huì)執(zhí)行erase了。
class Solution { public:/*** lru design* @param operators int整型vector<vector<>> the ops* @param k int整型 the k* @return int整型vector*/struct Node {int key, val;Node* pre, *nxt;Node(int k, int v):key(k), val(v){}};int K;unordered_map<int, Node*> k_pos;Node* head, *tail;void insert(int key, int value) {Node* newNode = new Node(key, value);newNode->nxt = head->nxt;newNode->pre = head;head->nxt->pre = newNode;head->nxt = newNode;k_pos[key] = newNode;}bool remove(int key) {if(k_pos.find(key) != k_pos.end()) {Node* tar = k_pos[key];tar->pre->nxt = tar->nxt;tar->nxt->pre = tar->pre;delete tar;k_pos.erase(key);return true;}return false;}void set(int key, int value) {remove(key);if(k_pos.size() >= K) {remove(tail->pre->key);}insert(key, value);}int get(int key) {if(k_pos.find(key) != k_pos.end()) {int ret = k_pos[key]->val;remove(key);insert(key, ret);return ret;}return -1;}vector<int> LRU(vector<vector<int> >& operators, int k) {// write code hereK = k;head = new Node(-1, -1);tail = new Node(-1, -1);head->nxt = tail;tail->pre = head;vector<int> ans;for(int i = 0; i<operators.size(); i++) {if(operators[i][0] == 1) {set(operators[i][1], operators[i][2]);} else {ans.push_back(get(operators[i][1]));}}return ans;} };重構(gòu)前較為復(fù)雜的代碼:
class Solution { public:/*** lru design* @param operators int整型vector<vector<>> the ops* @param k int整型 the k* @return int整型vector*/struct Node {int key, val;Node* pre, *nxt;Node(int k, int v):key(k), val(v){}};int K;unordered_map<int, Node*> k_pos;Node* head, *tail;bool remove(int key) {if(k_pos.find(key) != k_pos.end()) {Node* tar = k_pos[key];tar->pre->nxt = tar->nxt;tar->nxt->pre = tar->pre;delete tar;k_pos.erase(key);return true;}return false;}void set(int key, int value) {remove(key);if(k_pos.size() >= K) {remove(tail->pre->key);}Node* newNode = new Node(key, value);newNode->nxt = head->nxt;newNode->pre = head;head->nxt->pre = newNode;head->nxt = newNode;k_pos[key] = newNode;}int get(int key) {if(k_pos.find(key) != k_pos.end()) {int ret = k_pos[key]->val;remove(key);Node* newNode = new Node(key, ret);newNode->nxt = head->nxt;newNode->pre = head;head->nxt->pre = newNode;head->nxt = newNode;k_pos[key] = newNode;return ret;}return -1;}vector<int> LRU(vector<vector<int> >& operators, int k) {// write code hereK = k;head = new Node(-1, -1);tail = new Node(-1, -1);head->nxt = tail;tail->pre = head;vector<int> ans;for(int i = 0; i<operators.size(); i++) {if(operators[i][0] == 1) {set(operators[i][1], operators[i][2]);} else {ans.push_back(get(operators[i][1]));}}return ans;} };總結(jié)
以上是生活随笔為你收集整理的【牛客 - NC93】设计LRU缓存结构(模拟)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql设计资源目录售卖_MySQL目
- 下一篇: 【计蒜客 - 程序设计竞赛】商业信息共享