LeetCode ソリューションの概要 146. LRU キャッシュ

 ディレクトリリンク:

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;
    }
};

おすすめ

転載: blog.csdn.net/AA5279AA/article/details/133272276