【牛客 - NC93】设计LRU缓存结构(模拟)
設計LRU緩存結構_牛客題霸_牛客網
描述
設計LRU(最近最少使用)緩存結構,該結構在構造時確定大小,假設大小為 k ,并有如下兩個功能
1. set(key, value):將記錄(key, value)插入該結構
2. get(key):返回key對應的value值
提示:
1.某個key的set或get操作一旦發生,認為這個key的記錄成了最常使用的,然后都會刷新緩存。
2.當緩存的大小超過k時,移除最不經常使用的記錄。
3.輸入一個二維數組與k,二維數組每一維有2個或者3個數字,第1個數字為opt,第2,3個數字為key,value
若opt=1,接下來兩個整數key,?value,表示set(key,?value)
若opt=2,接下來一個整數key,表示get(key),若key未出現過或已被移除,則返回-1
對于每個opt=2,輸出一個答案
4.為了方便區分緩存里key與value,下面說明的緩存里key用""號包裹
要求:set和get操作復雜度均為?O(1)
示例1
輸入:
[[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]],3復制返回值:
[1,-1]復制說明:
[1,1,1],第一個1表示opt=1,要set(1,1),即將(1,1)插入緩存,緩存是{"1"=1} [1,2,2],第一個1表示opt=1,要set(2,2),即將(2,2)插入緩存,緩存是{"1"=1,"2"=2} [1,3,2],第一個1表示opt=1,要set(3,2),即將(3,2)插入緩存,緩存是{"1"=1,"2"=2,"3"=2} [2,1],第一個2表示opt=2,要get(1),返回是[1],因為get(1)操作,緩存更新,緩存是{"2"=2,"3"=2,"1"=1} [1,4,4],第一個1表示opt=1,要set(4,4),即將(4,4)插入緩存,但是緩存已經達到最大容量3,移除最不經常使用的{"2"=2},插入{"4"=4},緩存是{"3"=2,"1"=1,"4"=4} [2,2],第一個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復制返回值:
[1,-1,-1,3,4]復制
備注:
1≤K≤N≤105 ?2×109≤x,y≤2×109解題報告:
首先設計數據結構使用hash表+鏈表實現。
首先用鏈表來實現頁面緩存。用hash表來快速定位每個key對應的value是什么。方便進行get操作。
AC代碼:
優化后較為簡單的代碼:
即我們調用層,代碼十分清晰。具體實現層,實現了鏈表層面的insert和remove,順便更新下key就可以了。
注意點1:remove函數里面的k_pos.erase操作要放到if內,不然已經return了就不會執行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;} };重構前較為復雜的代碼:
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;} };總結
以上是生活随笔為你收集整理的【牛客 - NC93】设计LRU缓存结构(模拟)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql设计资源目录售卖_MySQL目
- 下一篇: 兴业银行信用卡好评排行榜 兴业信用卡哪个