dengxinyi 6 anos atrás
pai
commit
2578495ebb
1 arquivos alterados com 45 adições e 47 exclusões
  1. 45 47
      hard/146.lru-cache.go

+ 45 - 47
hard/146.lru-cache.go

@@ -1,81 +1,79 @@
 type biNode struct {
-	key  int
-	val  int
+	key int
+	val int
 	prev *biNode
 	next *biNode
 }
 
+type biList struct {
+	head *biNode
+	tail *biNode
+}
+
+func newBiList() *biList {
+	head, tail := &biNode{}, &biNode{}
+	head.next = tail
+	tail.prev = head
+	li := &biList{head, tail}
+	return li
+}
+
+func (li *biList) remove(node *biNode) {
+	node.prev.next = node.next
+	node.next.prev = node.prev
+}
+
+func (li *biList) insert(node *biNode) {
+	node.next = li.head.next
+	node.prev = li.head
+	li.head.next = node
+	node.next.prev = node
+}
+
 type LRUCache struct {
 	capacity int
 	size     int
 	cache    map[int]*biNode
-	head     *biNode
-	tail     *biNode
+	list     *biList
 }
 
 func Constructor(capacity int) LRUCache {
 	var lru LRUCache
 	lru.capacity = capacity
 	lru.cache = make(map[int]*biNode)
+	lru.list = newBiList()
 	return lru
 }
 
 func (this *LRUCache) Get(key int) int {
 	if node, ok := this.cache[key]; ok {
-		this.moveToHead(node)
+		this.list.remove(node)
+		this.list.insert(node)
 		return node.val
 	}
 	return -1
 }
 
-func (this *LRUCache) Put(key int, value int) {
+func (this *LRUCache) Put(key int, value int)  {
+	if this.capacity == 0 {
+		return
+	}
 	if node, ok := this.cache[key]; ok {
+		this.list.remove(node)
+		this.list.insert(node)
 		node.val = value
-		this.moveToHead(node)
 		return
-	} // Already exsist, update value & move to head
-	newHead := &biNode{key, value, nil, this.head}
-	if this.size == 0 {
-		this.head = newHead
-		this.tail = newHead
-	} else {
-		this.head.prev = newHead
-		this.head = newHead
 	}
-	this.cache[key] = this.head
-	this.size++                    // Not exsist, add new head
-	if this.size > this.capacity { // Remove tail
+	if this.size == this.capacity {
+		node := this.list.tail.prev
+		delete(this.cache, node.key)
+		this.list.remove(node)
 		this.size--
-		delete(this.cache, this.tail.key)
-		this.tail = this.tail.prev
-		if this.tail == nil {
-			this.head = nil
-		} else {
-			this.tail.next = nil
-		}
-	}
-}
-
-func (this *LRUCache) moveToHead(node *biNode) {
-	if node == this.head {
-		return
-	}
-	if node == this.tail {
-		this.tail.next = this.head
-		this.head.prev = this.tail
-		this.head = this.tail
-		this.tail = this.tail.prev
-		this.tail.next = nil
-		this.head.prev = nil
-		return
 	}
-	prev, next := node.prev, node.next
-	next.prev = prev
-	prev.next = next
-	node.prev = nil
-	node.next = this.head
-	this.head.prev = node
-	this.head = node
+	newNode := &biNode{key, value, nil, nil}
+	this.list.insert(newNode)
+	this.cache[key] = newNode
+	this.size++
 }
 
 /**