知識點:雜湊表、鍊錶
題目鏈結
題目描述
設計lru快取結構,該結構在構造時確定大小,假設大小為k,並有如下兩個功能
[要求]
set和get方法的時間複雜度為o(1)
某個key的set或get操作一旦發生,認為這個key的記錄成了最常使用的。
當快取的大小超過k時,移除最不經常使用的記錄,即set或get最久遠的。
若opt=1,接下來兩個整數x, y,表示set(x, y)
若opt=2,接下來乙個整數x,表示get(x),若x未出現過或已被移除,則返回-1
對於每個操作2,輸出乙個答案
示例1
輸入:[[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]],3
返回值:[1,-1]
說明:
第一次操作後:最常使用的記錄為(「1」, 1)
第二次操作後:最常使用的記錄為(「2」, 2),(「1」, 1)變為最不常用的
第三次操作後:最常使用的記錄為(「3」, 2),(「1」, 1)還是最不常用的
第四次操作後:最常用的記錄為(「1」, 1),(「2」, 2)變為最不常用的
第五次操作後:大小超過了3,所以移除此時最不常使用的記錄(「2」, 2),加入記錄(「4」, 4),並且為最常使用的記錄,然後(「3」, 2)變為最不常使用的記錄
備註:
解題思路
根據要求1 我們需要定義兩個方法set和get 由於這兩者時間複雜度為o(1) 我們就想到unordered_map能快速訪問資料我們結合要求2、3 要根據最常用的記錄 會移除最不經常用的 這裡就想到用雙向鍊錶首先定義結點node:key、value、前指標、後指標所以我們可以大致構建結構有乙個雜湊表用來登記key,value型別是node*型別,有頭結點和尾結點,和快取的大小初始化solution:頭結點和尾結點為空,快取大小
首先是set函式若不存在對應的key,說明沒出現過
把這個結點放入雜湊表
這個結點放入鍊錶的頭部
再是get函式未找到
在set和get函式都需要用 到把結點從鍊錶中刪除 再放入鍊錶的頭部 可單獨抽象出兩個函式
刪除結點函式放入函式
**
/*
1. 根據要求1 我們需要定義兩個方法set和get 由於這兩者時間複雜度為o(1) 我們就想到unordered_map能快速訪問資料
2. 我們結合要求2、3 要根據最常用的記錄 會移除最不經常用的 這裡就想到用雙向鍊錶
3. 首先定義結點node:key、value、前指標、後指標
4. 所以我們可以大致構建結構 有乙個雜湊表用來登記key,value型別是node*,有頭結點和尾結點,和快取的大小
5. 初始化solution:頭結點和尾結點為空,快取大小
6. 首先是set函式
- 查詢雜湊表,若雜湊表中存在對應的key
- 更新key對應結點中的值
- 並把這個結點從原來的鍊錶中刪除,放入鍊錶的頭部,記為最近操作的
- 若不存在對應的key,說明沒出現過
- 如果當前雜湊表中的大小 大於等於 規定快取的大小
- 刪除雜湊表中對應的值 tail->key
- 從鍊錶中刪除最後乙個結點
- 把這個結點放入雜湊表
- 這個結點放入鍊錶的頭部
7. 再是get函式
- 查詢雜湊表,若找到對應的key
- 記錄cache中對應key的結點的value
- 刪除並放入鍊錶的頭部
- 未找到
- 返回 -1
8. 在set和get函式都需要用 到把結點從鍊錶中刪除 再放入鍊錶的頭部 可單獨抽象出兩個函式
9. 刪除結點函式
- 如果該結點是頭結點 頭結點 = 頭結點的後結點
- 如果該結點是尾結點 尾結點 = 尾結點的前結點 ;尾結點的後面 = 空
- 該結點的前結點的後面 = 該結點的後結點 ; 該結點的後結點的前面 = 該結點的前面結點
10. 放入函式
- 如果放入的就是頭結點 返回
- 該結點的後面 = 頭結點 如果頭結點不為空 頭結點的前面 = 該結點 更新頭結點
- 如果尾結點為空 尾結點 = 頭結點
*/#include
"cheader.h"
struct node};
class
solution
}return ans;
}void
set(
int key,
int value)
else
node* n =
newnode
(key,value)
; cache[key]
= n;
insert
(n);}}
intget
(int key)
return-1
;}void
remove
(node* n)
else
}void
insert
(node* n)};
intmain()
;vector<
int> v2
; vector<
int> v3
;vector<
int> v4
; vector<
int> v5
;vector<
int> v6
; vectorint>> operators;
operators.
push_back
(v1)
;operators.
push_back
(v2)
;operators.
push_back
(v3)
; operators.
push_back
(v4)
;operators.
push_back
(v5)
;operators.
push_back
(v6)
;int k =3;
vector<
int> ans = s.
lru(operators, k)
;for
(int x:ans)
cout
}
牛客NC93 設計LRU快取結構
設計lru快取結構,該結構在構造時確定大小,假設大小為k,並有如下兩個功能 要求 set和get方法的時間複雜度為o 1 某個key的set或get操作一旦發生,認為這個key的記錄成了最常使用的。當快取的大小超過k時,移除最不經常使用的記錄,即set或get最久遠的。若opt 1,接下來兩個整數x...
牛客題霸 研發 NC93 設計LRU快取結構
本題鏈結 設計lru快取結構,該結構在構造時確定大小,假設大小為k,並有如下兩個功能 set key,value 將記錄 key,value 插入該結構 get key 返回key對應的value值 要求 set和get方法的時間複雜度為o 1 某個key的set或get操作一旦發生,認為這個key...
設計LRU快取結構
設計lru快取結構 設計lru快取結構,該結構在構造時確定大小,假設大小為k,並有如下兩個功能 要求 set和get方法的時間複雜度為o 1 某個key的set或get操作一旦發生,認為這個key的記錄成了最常使用的。當快取的大小超過k時,移除最不經常使用的記錄,即set或get最久遠的。輸入描述 ...