ディレクトリリンク:
Likou プログラミングの質問 - 解決策の概要_共有 + 録音 - CSDN ブログ
GitHub 同期問題解決プロジェクト:
https://github.com/ September26/java-algorithms
原題リンク:LeetCode 公式サイト - 世界中のオタクに愛されるテクノロジー成長プラットフォーム
説明する:
LRU(最も最近使用されていない)キャッシュ制約を満たすデータ構造を設計および実装してください 。
実装 LRUCache
クラス:
LRUCache(int capacity)
容量として 正の整数 を使用してcapacity
LRU キャッシュを初期化します。int get(int key)
キーワードがキャッシュに存在する場合はkey
キーワードの値を返し、存在しない場合はその値を返します-1
。void put(int key, int value)
キーワードがkey
すでに存在する場合は、そのデータ値を変更しvalue
、キーワードが存在しない場合は、グループをキャッシュに挿入しますkey-value
。挿入操作によりキーワードの数を超えた場合は 、 最も古い未使用のキーワードを削除するcapacity
必要があります 。
関数 get
を put
実行する必要がある O(1)
平均時間複雑さ。
例:
入力 ["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"] [[2], [1 , 1]、[2、2]、[1]、[3、3]、[2]、[4、4]、[1]、[3]、[4]] 出力 [null、null、null 、 1 , null, -1, null, -1, 3, 4] LRUCacheの説明 lRUCache = new LRUCache(2); lRUCache.put(1, 1); // キャッシュは {1=1} lRUCache.put(2) , 2 ); // キャッシュは {1=1, 2=2} lRUCache.get(1); // 1 を返します lRUCache.put(3, 3); // この操作はキーワード 2 を無効にし、キャッシュは{1 =1, 3=3} lRUCache.get(2); // -1 を返します(見つからない) lRUCache.put(4, 4); // この操作はキーワード 1 を無効にし、キャッシュは {4= 4, 3=3} lRUCache.get(1); // -1 を返します (見つからない) lRUCache.get(3); // 3 を返します lRUCache.get(4); // 4 を返します
ヒント:
1 <= capacity <= 3000
0 <= key <= 10000
0 <= value <= 105
- 最大 通話
2 * 105
数get
とput
問題解決のアイデア:
* 問題解決のアイデア:
* この質問の最も難しい部分は、実際には二重リンクされたリスト間の関係を扱うことです。
* 2 つのメソッド updateHead と updateTail を構築します。これらはそれぞれ、ノード変更後のヘッド ノードとテール ノードの処理を表します。
※ヘッドノードを処理する場合、カレントノードが既にヘッドノードである場合は処理する必要はありません。それ以外の場合は、電流の前のノードと次のノードを接続してから、電流をヘッド ノードに置きます。
* 末尾ノードを処理する場合、マップ内に 1 つしかない場合は現在のノードが末尾ノード、マップ長が 2 の場合は前のヘッダーが末尾ノード、現在のヘッダーが末尾ノードの場合の 3 つの状況があります。 , から切断します。 前ノードと前ノードの関係が末尾ノードとして設定されます。
コード:
class LRUCache
{
public:
class Node
{
public:
int key;
int val;
Node *next;
Node *pre;
Node(int mkey = 0, int mvalue = 0) : key(mkey), val(mvalue), next(nullptr), pre(nullptr){};
};
int maxSize = 0;
unordered_map<int, Node *> valueMap;
Node *header = nullptr;
Node *tail = nullptr;
LRUCache(int capacity)
{
maxSize = capacity;
}
int get(int key)
{
if (valueMap.find(key) == valueMap.end())
{
return -1;
}
Node *current = valueMap[key];
updateTail(current);
updateHead(current);
return valueMap[key]->val;
}
void put(int key, int value)
{
if (valueMap.find(key) != valueMap.end())
{
Node *current = valueMap[key];
current->val = value;
updateTail(current);
updateHead(current);
return;
}
if (valueMap.size() == maxSize)
{
removeNode();
}
addNode(key, value);
}
void addNode(int key, int value)
{
Node *current = new Node(key, value);
valueMap[key] = current;
updateTail(current);
updateHead(current);
}
/**
* 把current设置为header
*/
void updateHead(Node *current)
{
if (header == current)
{
return;
}
// 链表中删除当前节点
if (current->pre != nullptr)
{
current->pre->next = current->next;
}
if (current->next != nullptr)
{
current->next->pre = current->pre;
}
// 加入头节点
current->next = header;
current->pre = nullptr;
if (header != nullptr)
{
header->pre = current;
}
header = current;
}
void updateTail(Node *current)
{
// 如果长度为1时
if (valueMap.size() == 1)
{
tail = current;
return;
}
if (valueMap.size() == 2)
{
tail->pre = current;
tail = header;
}
else if (current == tail)
{
if (tail->pre != nullptr)
{
tail->pre->next = nullptr;
}
if (valueMap.size() > 1)
{
tail = current->pre;
}
}
}
void removeNode()
{
valueMap.erase(tail->key);
Node *tailPre = tail->pre;
if (tailPre == nullptr)
{
return;
}
tailPre->next = nullptr;
tail->pre = nullptr;
tail = tailPre;
}
};