NC93 設計LRU快取結構

2021-10-20 17:40:45 字數 3505 閱讀 9518

知識點:雜湊表、鍊錶

題目鏈結

題目描述

設計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最久遠的。輸入描述 ...