Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c08e615

Browse files
committed
feat: add solutions to lcof2 problem: No.031
1 parent 113ee57 commit c08e615

File tree

8 files changed

+983
-221
lines changed

8 files changed

+983
-221
lines changed

‎lcof2/剑指 Offer II 031. 最近最少使用缓存/README.md‎

Lines changed: 437 additions & 72 deletions
Large diffs are not rendered by default.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
struct Node {
2+
int k;
3+
int v;
4+
Node* prev;
5+
Node* next;
6+
7+
Node()
8+
: k(0)
9+
, v(0)
10+
, prev(nullptr)
11+
, next(nullptr) {}
12+
Node(int key, int val)
13+
: k(key)
14+
, v(val)
15+
, prev(nullptr)
16+
, next(nullptr) {}
17+
};
18+
19+
class LRUCache {
20+
public:
21+
LRUCache(int capacity)
22+
: cap(capacity)
23+
, size(0) {
24+
head = new Node();
25+
tail = new Node();
26+
head->next = tail;
27+
tail->prev = head;
28+
}
29+
30+
int get(int key) {
31+
if (!cache.count(key)) return -1;
32+
Node* node = cache[key];
33+
moveToHead(node);
34+
return node->v;
35+
}
36+
37+
void put(int key, int value) {
38+
if (cache.count(key)) {
39+
Node* node = cache[key];
40+
node->v = value;
41+
moveToHead(node);
42+
} else {
43+
Node* node = new Node(key, value);
44+
cache[key] = node;
45+
addToHead(node);
46+
++size;
47+
if (size > cap) {
48+
node = removeTail();
49+
cache.erase(node->k);
50+
--size;
51+
}
52+
}
53+
}
54+
55+
private:
56+
unordered_map<int, Node*> cache;
57+
Node* head;
58+
Node* tail;
59+
int cap;
60+
int size;
61+
62+
void moveToHead(Node* node) {
63+
removeNode(node);
64+
addToHead(node);
65+
}
66+
67+
void removeNode(Node* node) {
68+
node->prev->next = node->next;
69+
node->next->prev = node->prev;
70+
}
71+
72+
void addToHead(Node* node) {
73+
node->next = head->next;
74+
node->prev = head;
75+
head->next = node;
76+
node->next->prev = node;
77+
}
78+
79+
Node* removeTail() {
80+
Node* node = tail->prev;
81+
removeNode(node);
82+
return node;
83+
}
84+
};
85+
86+
/**
87+
* Your LRUCache object will be instantiated and called as such:
88+
* LRUCache* obj = new LRUCache(capacity);
89+
* int param_1 = obj->get(key);
90+
* obj->put(key,value);
91+
*/
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
public class LRUCache {
2+
class Node {
3+
public Node Prev;
4+
public Node Next;
5+
public int Key;
6+
public int Val;
7+
}
8+
9+
private Node head = new Node();
10+
private Node tail = new Node();
11+
private Dictionary<int, Node> cache = new Dictionary<int, Node>();
12+
private readonly int capacity;
13+
private int size;
14+
15+
public LRUCache(int capacity) {
16+
this.capacity = capacity;
17+
head.Next = tail;
18+
tail.Prev = head;
19+
}
20+
21+
public int Get(int key) {
22+
Node node;
23+
if (cache.TryGetValue(key, out node)) {
24+
moveToHead(node);
25+
return node.Val;
26+
}
27+
return -1;
28+
}
29+
30+
public void Put(int key, int Val) {
31+
Node node;
32+
if (cache.TryGetValue(key, out node)) {
33+
moveToHead(node);
34+
node.Val = Val;
35+
} else {
36+
node = new Node() { Key = key, Val = Val };
37+
cache.Add(key, node);
38+
addToHead(node);
39+
if (++size > capacity) {
40+
node = removeTail();
41+
cache.Remove(node.Key);
42+
--size;
43+
}
44+
}
45+
}
46+
47+
private void moveToHead(Node node) {
48+
removeNode(node);
49+
addToHead(node);
50+
}
51+
52+
private void removeNode(Node node) {
53+
node.Prev.Next = node.Next;
54+
node.Next.Prev = node.Prev;
55+
}
56+
57+
private void addToHead(Node node) {
58+
node.Next = head.Next;
59+
node.Prev = head;
60+
head.Next = node;
61+
node.Next.Prev = node;
62+
}
63+
64+
private Node removeTail() {
65+
Node node = tail.Prev;
66+
removeNode(node);
67+
return node;
68+
}
69+
}
70+
71+
/**
72+
* Your LRUCache object will be instantiated and called as such:
73+
* LRUCache obj = new LRUCache(capacity);
74+
* int param_1 = obj.Get(key);
75+
* obj.Put(key,Val);
76+
*/
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
type node struct {
2+
key, val int
3+
prev, next *node
4+
}
5+
6+
type LRUCache struct {
7+
capacity int
8+
cache map[int]*node
9+
head, tail *node
10+
}
11+
12+
func Constructor(capacity int) LRUCache {
13+
head := new(node)
14+
tail := new(node)
15+
head.next = tail
16+
tail.prev = head
17+
return LRUCache{
18+
capacity: capacity,
19+
cache: make(map[int]*node, capacity),
20+
head: head,
21+
tail: tail,
22+
}
23+
}
24+
25+
func (this *LRUCache) Get(key int) int {
26+
n, ok := this.cache[key]
27+
if !ok {
28+
return -1
29+
}
30+
this.moveToFront(n)
31+
return n.val
32+
}
33+
34+
func (this *LRUCache) Put(key int, value int) {
35+
n, ok := this.cache[key]
36+
if ok {
37+
n.val = value
38+
this.moveToFront(n)
39+
return
40+
}
41+
if len(this.cache) == this.capacity {
42+
back := this.tail.prev
43+
this.remove(back)
44+
delete(this.cache, back.key)
45+
}
46+
n = &node{key: key, val: value}
47+
this.pushFront(n)
48+
this.cache[key] = n
49+
}
50+
51+
func (this *LRUCache) moveToFront(n *node) {
52+
this.remove(n)
53+
this.pushFront(n)
54+
}
55+
56+
func (this *LRUCache) remove(n *node) {
57+
n.prev.next = n.next
58+
n.next.prev = n.prev
59+
n.prev = nil
60+
n.next = nil
61+
}
62+
63+
func (this *LRUCache) pushFront(n *node) {
64+
n.prev = this.head
65+
n.next = this.head.next
66+
this.head.next.prev = n
67+
this.head.next = n
68+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /