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 ( array_key_exists($key, $this->map) ) {
$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 ( array_key_exists($key, $this->map) ) {
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);
*/