Problem 1 LRU cache
https://leetcode.com/problems/lru-cache/
have been updated to new version
What is cache
为了不每次都重新检索,所先把检索的结果存下来,下次用户访问的时候直接给存好的检索结果
想到的是Map<key, value>, get a key by O(1)
look up operation(memo),如果计算过了,get上次计算的过,否则就重新算一遍
Cache 的本质就是map,只不过区别是,他是一个有capacity的map
What is used:
所有的增改查insert, update query都是used
put operation == insert/ update
get operation == query
remove operation == delete
注意,很多时候改,以为着是删/增
数据结构界的打工人:Map
Look up something(找什么,就是你所储存的东西) by something(透过什么来找,这个就是key)
经典的Use Case: 我需要知道我自己定义的Entry Reference在哪里,但是我propose的结果不具备优秀的查找功能
Map<Key, Entry Reference> locationMap
key通过什么找reference,Entry Reference你其他的数据结构储存
Example: Array Based PriorityQueue Update(key) Function
Map<key, index> indexMapForKeyinHeap + Heap
所有的操作,只要给我一个Key我都是可以拿到Entry Node, 又有了可以对时间排序的TreeSet/TreeMap
Summary
hybrid注意data structure, 先考虑每个元素cell里面有什么:
cell{key, value, index(hidden)}
再注意,多加结构的时候,必须用cell来做一个单位,会让思路更简单,比如说这道题如果用treeSet
map(key, cell) && container(cell)
并不能用map(key, index) && container(cell) , and Cell only have{key, index} ,why???
因为如果你需要知道这个元素里的其他资料
Method 1 TreeSet/ TreeMap + Map
Step 1 Use Case API design
Step 2: Detail Logic
get(key):
case 1 : map 里面有这个key
透过Map拿到Entry node(return的data就在里面)
update这个Entry Node的时间信息(TreeSet里的这个Entry做update--> delete + insert)
case 2: map里面没有这个key
return null
overall: O(logn)
put(key, value):
case 1: map 里面有这个key
想当于update这个key-value pair里的value
通过Map拿到Entry Node
update 这个Entry Node的value信息
update 这个Entry Node的时间信息
case 2: map 里面没有这个key
case 2.1 现在没有满
直接放一个新的Entry(update two maps)
case 2.2 现在满了
踢出一个leat recently used:也就是TreeSet里面时间戳
overall: O(logn)
timeStamp:
设计为当前LRU class里的一个feild
updated 准则,任何operation都需要update当前的信息
capacity:
设计为当前LRU class的一个field
注意put的details操作
FYI
TreeSet Version
TreeMap Version
Method 2 DoubleLinkedList
除了treeSet还有什么数据结构可以保持时间顺序? Queue==> FIFO时间顺序
Queue逻辑上的数据结构 => 怎么实现Queue
Queue<Integer> queue = new ArrayDeque<>();
Queue<Integer> queue = new LinkedList<>();
增删改查全是O(1)
Queue是逻辑数据结构,底层实现的是LinkedList
而DoubleLinkedList是因为O(1)的删除
那你得给我这个node reference,有了这个node reference,我做什么都是O(1),关键问题是,人家User insert/update/remove/query,人家给你的是key,不是node reference
打工人上线: Map<Key, DoublyListNode> locationMap + DoubleLinkedList(datainfo) DLL
Step 1 Use Case API design
get(key)
put(key, value)
Step 2: Detail Logic
get(key):
case 1 : map 里面有这个key
get the key==> 通过map拿到装有data的ListNode ==> ListNode里面的东西就是return的东西
update time order ==> remove this ListNode from LinkedList, then insert into Head
case 2: map里面没有这个key
return null
overall: O(logn)
put(key, value):
case 1: map 里面有这个key
update the value ==> 通过map拿到装有data的ListNode ==》 update ListNode
update the order ==> remove this ListNode from LinkedList, then insert into head
case 2: map 里面没有这个key
case 2.1 the cache is not full (check map 的size到不到capacity)
put the key value there
update the time order ==> insert into Head
case 2.2 现在满了
delete the oldest one ==> 踢出tail node
put the kye value there ==> insert into map and LL
update the time order ==> head
overall: O(1)
timeStamp:
设计为当前LRU class里的一个feild
updated 准则,任何operation都需要update当前的信息
capacity
设计为当前LRU class的一个field
Last updated