Leecode LRU缓存机制

Leecode 146. LRU缓存机制

https://leetcode-cn.com/problems/lru-cache/

利用php array的有序性

class LRUCache {
    private $capacity;
    private $map = []; 
    /**
     * @param Integer $capacity
     */
    function __construct($capacity) {
        $this->capacity = $capacity;
    }
  
    /**
     * @param Integer $key
     * @return Integer
     */
    function get($key) {
        $val = -1;
        $key = __CLASS__.$key;
        if ($this->map[$key]) {
            $val = $this->map[$key];
            unset($this->map[$key]);
            $this->map[$key] = $val;
        }


        return $val;
    }
  
    /**
     * @param Integer $key
     * @param Integer $value
     * @return NULL
     */
    function put($key, $value) {
        $key = __CLASS__.$key;
        if ($this->map[$key]) {
            unset($this->map[$key]);
        }
        if ( count($this->map) >= $this->capacity) {
            array_shift($this->map);
        }
        $this->map[$key] = $value;
    }
}


/**
 * Your LRUCache object will be instantiated and called as such:
 * $obj = LRUCache($capacity);
 * $ret_1 = $obj->get($key);
 * $obj->put($key, $value);
 */

利用双链表

class DLNode {
    public $key;
    public $value;
    public $prev;
    public $next;


    function __construct($key, $value) {
        $this->key = $key;
        $this->value = $value;
    }
}


class CacheQueue {
    public $size = 0;
    public $head;
    public $tail;


    function __construct() {
        $this->head = new DLNode(0, 0);
        $this->tail = new DLNode(0, 0);
        $this->head->next = $this->tail;
        $this->tail->prev = $this->head;
    }


    //头插法
    function addHead($node) {
        //node指向之前的第一个节点
        $node->next = $this->head->next;
        $node->next->prev = $node;
        $node->prev = $this->head;
        $this->head->next = $node;
        $this->size++;
    }


    //删除访问的节点,且把该节点移动到头部
    function moveToHead($node) {
        $node->prev->next = $node->next;
        $node->next->prev = $node->prev;
        $this->size--;
        $this->addHead($node);
    }


    //删除末尾元素,且返回删除节点
    function removeTail() {
        $node = NULL;
        if ($this->size > 0) {
            $node = $this->tail->prev;
            $node->prev->next = $this->tail;
            $this->tail->prev = $node->prev;
            $this->size--;
        }


        return $node;
    }


    function flushall() {
        while ($node = $this->removeTail()) {
            unset($node);
        }
    }
}


class LRUCache {
    public $cache; // 双向链表
    public $capacity; //存放限定最大空间
    public $map; //存放hashmap
    /**
     * @param Integer $capacity
     */
    function __construct($capacity) {
        $this->capacity = $capacity;
        $this->cache = new CacheQueue();
        $this->map = [];
    }
  
    /**
     * @param Integer $key
     * @return Integer
     */
    function get($key) {
        $res = -1; //初始化
        if ( array_key_exists($key, $this->map) ) {
            $res = $this->map[$key]->value; //获取返回值
            $this->cache->moveToHead($this->map[$key]); //将此节点移动到队首
        }
        
        return $res;
    }
  
    /**
     * @param Integer $key
     * @param Integer $value
     * @return NULL
     */
    function put($key, $value) {
        if ( array_key_exists($key, $this->map) ) {
            $node = & $this->map[$key];
            $node->value = $value;
            $this->cache->moveToHead($node);
        } else {
            if ($this->capacity === $this->cache->size) {
                $node = $this->cache->removeTail();
                unset($this->map[$node->key]);
            }


            $node = new DLNode($key, $value);
            $this->map[$key] = $node;
            $this->cache->addHead($node);
        }
    }


    function flushall() {
        $this->cache->flushall();
        $this->map = [];
    }
}


/**
 * Your LRUCache object will be instantiated and called as such:
 * $obj = LRUCache($capacity);
 * $ret_1 = $obj->get($key);
 * $obj->put($key, $value);
 */

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页