LeetCode146. LRU ็ผๅญ๐๐๐๐ไธญ็ญ
่ฏพๅไฝไธ
้ฎ้ขๆ่ฟฐ
ๅๆ้พๆฅ๏ผ146. LRU ็ผๅญ
่ฏทไฝ ่ฎพ่ฎกๅนถๅฎ็ฐไธไธชๆปก่ถณ 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 <= 30000 <= key <= 100000 <= value <= 105- ๆๅค่ฐ็จ
2 * 105ๆฌกgetๅput
ไปฃ็ ๅฎ็ฐ
Java
class LRUCache {
Map<Integer, Node> map = new HashMap();
int capacity;
int size;
Node head;
Node tail;
public LRUCache(int capacity) {
this.capacity = capacity;
this.size = 0;
this.head = new Node(-1, -1);
this.tail = new Node(-2, -2);
head.next = tail;
tail.pre = head;
}
public int get(int key) {
// ๅคๆญๆฏๅฆๅญๅจ
Node tmp = map.get(key);
if(tmp != null){
// ๅ ้ค
delete(tmp);
insertTohead(tmp);
return tmp.value;
}
return -1;
}
public void put(int key, int value) {
// ๅคๆญkeyๆฏๅฆๅญๅจ
Node tmp = map.get(key);
if(tmp != null){
// ๅ ้ค
delete(tmp);
// ๆๅ
ฅๅฐๅคด้จ
tmp.value = value;
insertTohead(tmp);
return;
}
// ไธๅญๅจ
Node newHead = new Node(key, value);
// ๆๅ
ฅๅฐๅคด้จ
insertTohead(newHead);
size++;
map.put(key, newHead);
if(size > capacity){
// ๅ ้คๆๅไธไธช่็น
Node res = tail.pre;
delete(res);
map.remove(res.key);
size--;
}
}
// ๆๅ
ฅๅฐๅคด้จhead->tmp->....
public void insertTohead(Node tmp){
tmp.next = head.next;
head.next.pre = tmp;
head.next = tmp;
tmp.pre = head;
}
// ๅ ้คtmp่็น
public void delete(Node tmp){
tmp.pre.next = tmp.next;
tmp.next.pre = tmp.pre;
}
// ๅฎไนๅๅ้พ่กจ
class Node{
int value;
int key;
Node next;
Node pre;
public Node(int key, int value){
this.key = key;
this.value = value;
}
}
// ้ข่ฏไธญ่็ๆบๅค=ใ้ขๅคงๅ=ใๆๆก
/*ๆนๆณ1:ๅ้พ่กจ
head->(4,4)->(3,3)->null
put:
1.ไธๅญๅจ๏ผ็ดๆฅๆ่็นๆๅ
ฅๅฐๅคด้จ
2.ๅฆๆๅญๅจ๏ผๆ่ฟไธช่็นไป้พ่กจไธญๅ ้ค๏ผๅนถไธๆๅ
ฅๅฐๅคด้จ
3.ๅฆๆๆๅ
ฅๅผ๏ผ่ถ
่ฟๆๅคงๅฎน้๏ผๅ้พ่กจๆๅไธไธช่็นๅ ้ค
get:ๅฆๆๅญๅจ๏ผๅ่ฟๅ๏ผๅนถไธๆ่็นๅ ้ค+ๆๅ
ฅๅฐ้พ่กจๅคด้จ
ๅฆๆไธๅญๅจ๏ผๅ็ดๆฅ่ฟๅ-1๏ผๅ
ถไป้ฝไธ็จๆไฝ
ๆถ้ดๅคๆๅบฆ๏ผput:O(n). get:O(n)
# ไผๅ1๏ผๅ ๅๅธ่กจ <key,Node>
็ไผผO(1)๏ผไฝๅ
ถๅฎไธ่ฝO(1)๏ผๅ ไธบ่ฟ้่ฆๅ ้ค่็น๏ผๅ ้ค่็น้่ฆ
ๆพๅฐๅ้ฉฑ่็น๏ผๆพๅ้ฉฑ่็น็่ฟ็จไน้่ฆO๏ผn)
# ็ปง็ปญไผๅ๏ผๅๅ้พ่กจ + ๅๅธ่กจ
ๅฏไปฅO(1)
ๆผ็คบ๏ผ
head<->(3,3)<->(4,4)<->tail
*/
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
Python
class LRUCache(object):
def __init__(self, capacity):
"""
:type capacity: int
"""
self.map = {}
self.capacity = capacity
self.size = 0
self.head = Node(-1, -1)
self.tail = Node(-2, -2)
self.head.next = self.tail
self.tail.pre = self.head
def get(self, key):
"""
:type key: int
:rtype: int
"""
# ๅคๆญๆฏๅฆๅญๅจ
tmp = self.map.get(key)
if tmp:
# ๅ ้ค
self.delete(tmp)
self.insertTohead(tmp)
return tmp.value
return -1
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: None
"""
# ๅคๆญkeyๆฏๅฆๅญๅจ
tmp = self.map.get(key)
if tmp:
# ๅ ้ค
self.delete(tmp)
# ๆๅ
ฅๅฐๅคด้จ
tmp.value = value
self.insertTohead(tmp)
return
# ไธๅญๅจ
newHead = Node(key, value)
# ๆๅ
ฅๅฐๅคด้จ
self.insertTohead(newHead)
self.size += 1
self.map[key] = newHead
if self.size > self.capacity:
# ๅ ้คๆๅไธไธช่็น
res = self.tail.pre
self.delete(res)
self.map.pop(res.key)
self.size -= 1
# ๆๅ
ฅๅฐๅคด้จhead->tmp->....
def insertTohead(self, tmp):
tmp.next = self.head.next
self.head.next.pre = tmp
self.head.next = tmp
tmp.pre = self.head
# ๅ ้คtmp่็น
def delete(self, tmp):
tmp.pre.next = tmp.next
tmp.next.pre = tmp.pre
# ๅฎไนๅๅ้พ่กจ
class Node:
def __init__(self, key, value):
self.key = key
self.value = value
self.next = None
self.pre = None
C++
class LRUCache {
public:
LRUCache(int capacity) {
this->capacity = capacity;
size = 0;
// ๅๅงๅๅคดๅฐพ่็น
this->head = new Node(-1, -1);
this->tail = new Node(-2, -2);
head->next = tail;
tail->pre = head;
}
int get(int key) {
// ๅคๆญๆฏๅฆๅญๅจ
Node* tmp = map[key];
if(tmp != nullptr){
// ๅ ้ค
deleteNode(tmp);
// ๆๅ
ฅๅฐๅคด้จ
insertToHead(tmp);
return tmp->value;
}
return -1;
}
void put(int key, int value) {
// ๅคๆญkeyๆฏๅฆๅญๅจ
Node* tmp = map[key];
if(tmp != nullptr){
// ๅ ้ค
deleteNode(tmp);
// ๆๅ
ฅๅฐๅคด้จ
tmp->value = value;
insertToHead(tmp);
return;
}
// ไธๅญๅจ
Node* newHead = new Node(key, value);
// ๆๅ
ฅๅฐๅคด้จ
insertToHead(newHead);
size++;
map[key] = newHead;
if(size > capacity){
// ๅ ้คๆๅไธไธช่็น
Node* res = tail->pre;
deleteNode(res);
map.erase(res->key);
size--;
}
}
private:
// ๅฎไนๅๅ้พ่กจ
struct Node{
int value;
int key;
Node* next;
Node* pre;
Node(int k, int v){
this->key = k;
this->value = v;
next = nullptr;
pre = nullptr;
}
};
unordered_map<int, Node*> map; // key->Nodeๆ้
int capacity; // ๆๅคงๅฎน้
int size; // ๅฝๅๅคงๅฐ
Node* head; // ๅๅ้พ่กจๅคด่็น
Node* tail; // ๅๅ้พ่กจๅฐพ่็น
// ๆๅ
ฅๅฐๅคด้จhead->tmp->....
void insertToHead(Node* tmp){
tmp->next = head->next;
head->next->pre = tmp;
head->next = tmp;
tmp->pre = head;
}
// ๅ ้ค่็น
void deleteNode(Node* tmp){
tmp->pre->next = tmp->next;
tmp->next->pre = tmp->pre;
}
};
Go
type LRUCache struct {
mapCache map[int]*Node
capacity int
size int
head, tail *Node
}
type Node struct {
key, value int
prev, next *Node
}
// ๆ้ ๅฝๆฐ
func Constructor(capacity int) LRUCache {
lru := LRUCache{
mapCache: make(map[int]*Node),
capacity: capacity,
size: 0,
head: &Node{key: -1, value: -1},
tail: &Node{key: -2, value: -2},
}
lru.head.next = lru.tail
lru.tail.prev = lru.head
return lru
}
// getๆนๆณ
func (this *LRUCache) Get(key int) int {
if node, ok := this.mapCache[key]; ok {
// ๅฆๆๅญๅจ๏ผๅ ้ค่ฏฅ่็นๅนถๆๅ
ฅๅฐๅคด้จ
this.deleteNode(node)
this.insertToHead(node)
return node.value
}
return -1
}
// putๆนๆณ
func (this *LRUCache) Put(key int, value int) {
if node, ok := this.mapCache[key]; ok {
// ๅฆๆๅญๅจ๏ผๅ ้ค่ฏฅ่็นๅนถๆๅ
ฅๅฐๅคด้จ
this.deleteNode(node)
node.value = value
this.insertToHead(node)
} else {
// ๅฆๆไธๅญๅจ๏ผๅๅปบๆฐ่็นๅนถๆๅ
ฅๅฐๅคด้จ
newNode := &Node{key: key, value: value}
this.insertToHead(newNode)
this.mapCache[key] = newNode
this.size++
if this.size > this.capacity {
// ๅฆๆ่ถ
่ฟๆๅคงๅฎน้๏ผๅ ้คๅฐพ้จ่็น
tailNode := this.tail.prev
this.deleteNode(tailNode)
delete(this.mapCache, tailNode.key)
this.size--
}
}
}
// ๅจๅคด้จๆๅ
ฅไธไธช่็น
func (this *LRUCache) insertToHead(node *Node) {
node.next = this.head.next
this.head.next.prev = node
this.head.next = node
node.prev = this.head
}
// ๅ ้คไธไธช่็น
func (this *LRUCache) deleteNode(node *Node) {
node.prev.next = node.next
node.next.prev = node.prev
}