Leetcode LRU Cache

twisted-fate發表於2019-06-01

覆盤

LeetCode LRU Cache

人生第三道 hard 題 , 不容易啊

第一次為了一道題重寫和優化虛擬碼 , 感覺清晰了許多

排查問題的時候花了一點時間 , 應該要寫一個列印連結串列的 helper 函式 , 做 tree 的題的時候也要一個列印 tree 的函式

錯誤先截圖下來 , 明天再覆盤 , 睡覺啦!!

LeetCode LRU Cache

LeetCode LRU Cache

LeetCode LRU Cache

圖片來源:https://zhuanlan.zhihu.com/p/34133067

LeetCode LRU Cache

LeetCode LRU Cache

第二版虛擬碼

DLinkedNode {
    val
    post 
    pre
}

LRUCache {
    map[key]node
    count
    capacity
    head
    tail
}

init {
    head.post=tail
    tail.pre=head

    count=0
    capacity=capacity
}

get(k) {
    if key in map
        node=map[key]
        if not at list head
            moveToHead(node)

    else
        return -1
}

put(k,v) {
    if in map
        node = map[k]
        node.val=v
        moveToHead(node)
    else
        if list full
            removeNode(tail.pre)
            delete(map,k)

            new=Node{v}
            addNode(new)
            map[k]=new
        else
            new=Node{v}
            newNode = addNode(new)
            map[k]=new
            count++
}

// move node right after head
moveToHead(node) {
    removeNode(node)
    addNode(node)
}

// remove from list
removeNode(node) {
    post=node.post
    pre=node.pre

    pre.post=post
    post.pre=pre
}

// add node after head
addNode(node) {

    head.post=node
    node.pre=head
    node.post=tail
    tail.pre=node
}

go 實現

 type DLinkedNode struct {
    Key int
    Val int
    Next *DLinkedNode
    Last *DLinkedNode
}

type LRUCache struct {
    DMap map[int]*DLinkedNode
    Count int
    Capacity int
    Head *DLinkedNode //dummy head
    Tail *DLinkedNode //dummy tail
}

func Constructor(capacity int) LRUCache {
    head:=DLinkedNode{}
    tail:=DLinkedNode{}
    head.Next=&tail
    tail.Last=&head

    return LRUCache{DMap:make(map[int]*DLinkedNode),Count:0,Capacity:capacity,Head:&head,Tail:&tail}
}

func (this *LRUCache) Get(key int) int {
    if _,ok:=this.DMap[key];ok {
        node:=this.DMap[key]
        this.moveToHead(node)
        return node.Val
    } else {
        return -1
    }
}

func (this *LRUCache) Put(key int, value int)  {
    if _,ok:=this.DMap[key];ok {
        node:=this.DMap[key]
        node.Val=value
        this.moveToHead(node)
    } else {
        if this.Count>=this.Capacity {
            delete(this.DMap,this.Tail.Last.Key)
            this.removeNode(this.Tail.Last)

            new:=DLinkedNode{Val:value,Key:key}
            this.addNode(&new)
            this.DMap[key]=&new
        } else {
            new:=DLinkedNode{Val:value,Key:key}
            this.addNode(&new)
            this.DMap[key]=&new
            this.Count++
        }
    }

}

func (t *LRUCache) moveToHead(node *DLinkedNode) {
    t.removeNode(node)
    t.addNode(node)
}

func (t *LRUCache) removeNode(node *DLinkedNode) {
    next:=node.Next
    last:=node.Last

    last.Next=next
    next.Last=last
}

func (t *LRUCache) addNode(node *DLinkedNode) {
    headNext:=t.Head.Next
    t.Head.Next=node
    node.Last=t.Head
    node.Next=headNext
    headNext.Last=node
}

第一版虛擬碼:

type LRUCache struct {
   NodeMap map[]
   DataLinkedList DLList
}

func Constructor(capacity int) LRUCache {

}

func (this *LRUCache) Get(key int) int {
    if key in map 
        if not in list head
            del from list
            insert into list top

        return map[key].val
    else
        return -1
}

func (this *LRUCache) Put(key int, value int)  {

if not in map
    if list is not full
        insert into list top   // add node
        insert into map

    if list is full
        remove tail data from list  // remove node
        remove tail data from map
        insert into list top //add node
        insert into map

if in map
    delete node
    insert into head
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * obj := Constructor(capacity);
 * param_1 := obj.Get(key);
 * obj.Put(key,value);
 */
definition:
lru 關鍵在於引入了一個高效的快取淘汰機制
using a hashmap to store node in double linked list
a limit variable to constraint len of list

a double linked list

two key operation :

LRU initial :

hashmap make(map[int]Node)

count=0 // len of exist val

capacity=capicity // capacity of list

head node = new Node , head.pre=null  // 

tail node = new Node , tail.post=null

head.post=tail
tail=pre=head

pesudo code for Double Linked List:

DoubleLinkedNode Design

int key
int val
pre Node
post Node

addNode(node)
    headPost = head.post

    head.post=node
    node.pre=head

    node.post=headpost
    headpost.pre=node

removeNode(node)
    pre=node.pre
    post=node.post

    pre.post=post
    post.pre=pre

moveToHead(node)
    removeNode(node)
    addNode(node)
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章