アルゴリズム - LRU キャッシュ アルゴリズムの設計

要件: LRU (Least Recent Used) キャッシュ制約を満たすデータ構造を設計および実装してください。
get 関数と put 関数は、平均時間計算量 O(1) で実行する必要があります。

アイデア:辞書 + 二重リンクリストを
使用する図:LRUアルゴリズム図

迅速:

public class Solution {
    
    

    class Node {
    
    
        //需要存储key 移除key-value需要 key
        var key: Int
        var value: Int
        var left: Node?
        var right: Node?
        init(key :Int=0, value: Int=0, left: Node?=nil, right: Node?=nil) {
    
    
            self.key = key
            self.value = value
            self.left = left
            self.right = right
        }
    }
    
    private var dic = Dictionary<Int, Node>.init()
    private var capacity = 0
    private var headNode = Node.init(key: -1, value: -1, left: nil, right: nil)
    private var tailNode = Node.init(key: -1, value: -1, left: nil, right: nil)

    init(_ capacity: Int) {
    
    
        self.capacity = capacity
        self.headNode.right = self.tailNode
        self.tailNode.left = self.headNode
    }
    
    func get(_ key: Int) -> Int {
    
    
        if !self.dic.keys.contains(key){
    
    
            return -1
        }else{
    
    
            self.swapNode(self.dic[key]!)
            return self.dic[key]!.value
        }
    }
    
    func set(_ key: Int, _ value: Int) {
    
    
        if !self.dic.keys.contains(key){
    
    
            let node = Node.init(key: key, value: value, left: nil, right: nil)
            if self.dic.count < self.capacity {
    
    
                self.addNodeToFirst(node)
                self.dic.updateValue(node, forKey: key)
            }else{
    
    
                self.addNodeToFirst(node)
                self.dic.updateValue(node, forKey: key)
                //移除最久未使用(重要)
                self.dic.removeValue(forKey: self.tailNode.left!.key)
                self.removeNode(self.tailNode.left!)
            }
        }else{
    
    
            let node = self.dic[key]!
            node.value = value
            self.swapNode(node)
        }
    }
    
    private func swapNode(_ node: Node) {
    
    
        if node.left!.value != -1{
    
    
            //移除先前节点
            self.removeNode(node)
            //插入节点
            self.addNodeToFirst(node)
        }
    }
   
    private func addNodeToFirst(_ node: Node) {
    
    
        node.right = self.headNode.right
        self.headNode.right!.left = node
        self.headNode.right = node
        node.left = self.headNode
    }
    
    private func removeNode(_ node: Node) {
    
    
        node.left!.right = node.right
        node.right!.left = node.left
    }
    
}

おすすめ

転載: blog.csdn.net/weixin_44758107/article/details/127881755