146. LRU緩存機制

運用你所掌握的數據結構,設計和實現一個??LRU (最近最少使用) 緩存機制。它應該支持以下操作: 獲取數據 get 和 寫入數據 put 。

獲取數據 get(key) - 如果密鑰 (key) 存在于緩存中,則獲取密鑰的值(總是正數),否則返回 -1。
寫入數據 put(key, value) - 如果密鑰不存在,則寫入其數據值。當緩存容量達到上限時,它應該在寫入新數據之前刪除最近最少使用的數據值,從而為新的數據值留出空間。

進階:

你是否可以在?O(1) 時間復雜度內完成這兩種操作?

示例:

LRUCache cache = new LRUCache( 2 /* 緩存容量 */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1); ? ? ? // 返回 ?1
cache.put(3, 3); ? ?// 該操作會使得密鑰 2 作廢
cache.get(2); ? ? ? // 返回 -1 (未找到)
cache.put(4, 4); ? ?// 該操作會使得密鑰 1 作廢
cache.get(1); ? ? ? // 返回 -1 (未找到)
cache.get(3); ? ? ? // 返回 ?3
cache.get(4); ? ? ? // 返回 ?4

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/lru-cache
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。

解法:?

#include <iostream>
#include <unordered_map>
#include <memory>
#include <list>
#include <utility>
using namespace std;class LRUCache
{
public:LRUCache(int capacity) //緩存容量{cap = capacity;}/*存在于緩存中,則獲取密鑰的值(總是正數),否則返回 -1。獲取數據 get(key) - 如果密鑰 (key) */int get(int key)  {auto it = m.find(key);if (it == m.end()) return -1;l.splice(l.begin(), l, it->second);return it->second->second;}/*寫入數據 put(key, value) - 如果密鑰不存在,則寫入其數據值。當緩存容量達到上限時,它應該在寫入新數據之前刪除最近最少使用的數據值,從而為新的數據值留出空間*/void put(int key, int value){auto it = m.find(key);if (it != m.end())l.erase(it->second);l.push_front(make_pair(key, value));m[key] = l.begin();if (m.size() > cap){int k = l.rbegin()->first;l.pop_back();m.erase(k);}}private:int cap;list<pair<int/*關鍵字*/, int>> l;unordered_map<int/*關鍵字*/, list<pair<int, int>>::iterator> m;
};int main()
{LRUCache cache(2 /* 緩存容量 */);cache.put(1, 1);cache.put(2, 2);cout << cache.get(1) << endl;       // 返回  1cache.put(3, 3);    // 該操作會使得密鑰 2 作廢cout << cache.get(2) << endl;       // 返回 -1 (未找到)cache.put(4, 4);     // 該操作會使得密鑰 1 作廢cout << cache.get(1) << endl;       // 返回 -1 (未找到)cout << cache.get(3) << endl;       // 返回  3cout << cache.get(4) << endl;       // 返回  4return 0;
}

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385384.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385384.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385384.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

dup和dup2函數

#include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd); 作用&#xff1a;dup函數實現對一個文件的文件描述符進行復制&#xff0c;復制之后該進程就會新增加一一個文件描述符指向該文件&#xff08;即實現同一個文件對應多個文件描述符&#xff0…

fcntl函數(網絡編程會用)

#include <unistd.h> #include <fcntl.h> int fcntl&#xff08;int fd, int cmd&#xff09;&#xff1b; int fcntl&#xff08;int fd, int cmd, long arg&#xff09;&#xff1b;//long 長整型 int fcntl&#xff08;int fd, int cmd, struct flock *lock…

189. 旋轉數組

給定一個數組&#xff0c;將數組中的元素向右移動 k 個位置&#xff0c;其中 k 是非負數。 示例 1: 輸入: [1,2,3,4,5,6,7] 和 k 3 輸出: [5,6,7,1,2,3,4] 解釋: 向右旋轉 1 步: [7,1,2,3,4,5,6] 向右旋轉 2 步: [6,7,1,2,3,4,5] 向右旋轉 3 步: [5,6,7,1,2,3,4]示例 2: 輸…

58. 最后一個單詞的長度

給定一個僅包含大小寫字母和空格 的字符串&#xff0c;返回其最后一個單詞的長度。 如果不存在最后一個單詞&#xff0c;請返回 0 。 說明&#xff1a;一個單詞是指由字母組成&#xff0c;但不包含任何空格的字符串。 示例: 輸入: "Hello World" 輸出: 5 clas…

CPU和MMU(內存管理單元)

CPU的架構&#xff1a;要求能夠理解從源程序到微指令的整個經歷過程&#xff1a;存儲器的層次結構&#xff08;網絡資源下載到硬盤、磁盤緩存、內存、Cache、寄存器&#xff09;&#xff1b;CPU的四大部分&#xff1a;ALU、CU、中斷系統和寄存器&#xff1b;程序執行的整個過程…

【C++ Primer | 09】容器適配器

一、stack s.push(): 向棧內壓入一個成員&#xff1b; s.pop(): 從棧頂彈出一個成員&#xff1b; s.empty(): 如果棧為空返回true&#xff0c;否則返回false&#xff1b; s.top(): 返回棧頂&#xff0c;但不刪除成員&#xff1b; s.size(): 返回棧內元素…

進程控制塊PCB(進程描述符)

&#xff08;1&#xff09;PCB 每個進程在內核中都有一個進程控制塊&#xff08;PCB&#xff09;來維護進程相關的信息&#xff0c;Linux內核的進程控制塊是task_struct結構體。grep -r “task_struct” / 可以查找根目錄下&#xff0c;包含task_struct的文件文件。或者 find…

103. 二叉樹的鋸齒形層次遍歷

給定一個二叉樹&#xff0c;返回其節點值的鋸齒形層次遍歷。&#xff08;即先從左往右&#xff0c;再從右往左進行下一層遍歷&#xff0c;以此類推&#xff0c;層與層之間交替進行&#xff09;。 例如&#xff1a; 給定二叉樹 [3,9,20,null,null,15,7], 3 / \ 9 20 /…

fork、getpid、getppid函數

#include <unistd.h> pid_t fork(void); 作用&#xff1a;創建一個子進程。 到目前為止&#xff0c;我們可以直到兩種創建進程的方法&#xff1a;1. 通過執行二進制文件來創建一個進程&#xff0c;如&#xff1a;./a.out /bin/ls&#xff1b;2.通過fork函數來創建一個…

107. 二叉樹的層次遍歷 II

給定一個二叉樹&#xff0c;返回其節點值自底向上的層次遍歷。 &#xff08;即按從葉子節點所在層到根節點所在的層&#xff0c;逐層從左向右遍歷&#xff09; 例如&#xff1a; 給定二叉樹 [3,9,20,null,null,15,7], 3/ \9 20/ \15 7返回其自底向上的層次遍歷為&#xff…

循環創建N個子進程

以循環創建5個進程為例&#xff0c;給出如下代碼&#xff0c;分析其錯誤&#xff1a; #include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(void) {int i;pid_t pid;printf("xxxxxxxxxxx\n");for (i 0; i < 5; i){pid fork…

【C++ Primer | 19】控制內存分配

1. 測試代碼&#xff1a; #include <iostream> #include <new> #include <cstring> #include <cstdlib> using namespace std;void* operator new(size_t size) {cout << "global Override operator new" << endl;if (void* p…

getuid、geteuid、getgid和getegid函數

#include <unistd.h> #include <sys/types.h> uid_t getuid(void); uid_t geteuid(void); 作用&#xff1a;getuid返回當前進程的實際用戶ID&#xff1b;geteuid返回當前用戶的有效用戶ID。這兩個總是成功&#xff0c;不會失敗。 #include <unistd.h> #…

【第15章】虛函數

一、為什么基類中的析構函數要聲明為虛析構函數&#xff1f; 直接的講&#xff0c;C中基類采用virtual虛析構函數是為了防止內存泄漏。具體地說&#xff0c;如果派生類中申請了內存空間&#xff0c;并在其析構函數中對這些內存空間進行釋放。假設基類中采用的是非虛析構函數&am…

進程共享(讀時共享寫時復制)

父子進程之間在剛fork后。父子相同處: 全局變量、.data、.bbs、.text、棧、堆、環境變量、用戶ID、宿主目錄&#xff08;進程用戶家目錄&#xff09;、進程工作目錄、信號處理方式等等&#xff0c;即0~3G的用戶空間是完全一樣的。父子不同處: 1.進程ID 2.fork返回值 3.父進…

【C++ Primer | 08】IO庫

一、istringstream類 描述&#xff1a;從流中提取數據&#xff0c;支持 >> 操作 這里字符串可以包括多個單詞&#xff0c;單詞之間使用空格分開 #include <iostream> #include <sstream> using namespace std; int main() {istringstream istr(&quo…

gdb調試(如何跟蹤指定進程)

使用gdb調試的時候&#xff0c;gdb只能跟蹤一個進程。可以在fork函數調用之前&#xff0c;通過指令設置gdb調試工具跟蹤父進程或者是跟蹤子進程。默認跟蹤父進程。 set follow-fork-mode child 命令設置gdb在fork之后跟蹤子進程。 set follow-fork-mode parent 設置跟蹤父進程…

【Leetcode | 01】Backtracking

回溯算法序號題號117. 電話號碼的字母組合222. 括號生成 39. 組合總和 40. 組合總和 II 46. 全排列 47. 全排列 II 60. 第k個排列 77. 組合 78. 子集 90. 子集 II 93. 復原IP地址 131. 分割回文串 216. 組合總和 III 306. 累加數 357. 計算各個位數不同的數字個數 401. 二進…

1033. 舊鍵盤打字(20)

舊鍵盤上壞了幾個鍵&#xff0c;于是在敲一段文字的時候&#xff0c;對應的字符就不會出現。現在給出應該輸入的一段文字、以及壞掉的那些鍵&#xff0c;打出的結果文字會是怎樣&#xff1f; 輸入格式&#xff1a; 輸入在2行中分別給出壞掉的那些鍵、以及應該輸入的文字。其中對…

1038. 統計同成績學生(20)

本題要求讀入N名學生的成績&#xff0c;將獲得某一給定分數的學生人數輸出。 輸入格式&#xff1a; 輸入在第1行給出不超過105的正整數N&#xff0c;即學生總人數。隨后1行給出N名學生的百分制整數成績&#xff0c;中間以空格分隔。最后1行給出要查詢的分數個數K&#xff08;不…