这道题最近热度比较高,就试着用两种写法就整了整,第一种是模仿大佬写的,用map去写的,第二种是用对象键值对+链表写的。 原题连接:leetcode-cn.com/problems/lr…
原题最关键的地方在于函数 get
和 put
必须以 O(1)
的平均时间复杂度运行。这也是为什么我们会采用键值对+双向链表 或者map。map不多说了。键值对+双向链表才是此题的精髓。先让我们看看双向链表的的基本属性。
class NodeLink {
public next // 下一个链表
public pre // 上一个链表
public val // 值
public key // 键
constructor(val, key?, next?, pre?) {
this.val = val
this.key = key
this.next = next
this.pre = pre
}
}
LinkMap类是此题的关键,几个关键的属性headLink,为了能够快速的添加移动元素到头部。 footLink为了能够快速的删除尾部数据。
class LRUCache {
private capacity:number
private caches:Map<any,any> =new Map()
constructor(capacity: number) {
this.capacity = capacity
}
get(key: number): number {
const cache:any = this.caches.get(key)
if(typeof cache === 'undefined'){
return -1
}
this.caches.delete(key)
this.caches.set(key,cache)
return cache
}
put(key: number, value: number): void {
if( this.caches.has(key)){
this.caches.delete(key)
}
this.caches.set(key,value)
const keys:any = this.caches.keys()
// @ts-ignore
while(this.caches.size > this.capacity){
this.caches.delete(keys.next().value)
}
}
}
```
```
第二种写法
```
class NodeLink {
public next
public pre
public val
public key
constructor(val, key?, next?, pre?) {
this.val = val
this.key = key
this.next = next
this.pre = pre
}
}
class LinkMap {
// map
public map: any = {}
// 顶部的链表
private headLink: NodeLink = new NodeLink(-1)
private footLink: NodeLink = new NodeLink(-1)
private len: number = 0
constructor() {
// 初始 头尾向连
this.headLink.next = this.footLink
this.footLink.pre = this.headLink
}
// 保存的数据长度
size() {
return this.len
}
// 保存
set(key: any, value: any) {
let node: NodeLink
if (this.has(key)) {
node = this.map[key]
node.val = value
this.moveToHead(node)
// 如果下一个没有说明最后一个
} else {
node = new NodeLink(value, key)
this.addToHead(node)
this.len++
}
this.map[key] = node
}
// 前后交换
swipe(node) {
node.pre.next = node.next
node.next.pre = node.pre
}
// 添加到头部
addToHead(node) {
node.pre = this.headLink
node.next = this.headLink.next
this.headLink.next.pre = node
this.headLink.next = node
}
// 交换到头部
moveToHead(node) {
this.swipe(node)
this.addToHead(node)
}
// 判断是否存在 此 node
has(key: any) {
return this.map[key] != undefined
}
// 获取数据
get(key: any) {
return this.map[key]
}
// 删除尾部
deleteLast() {
this.map[this.footLink.pre.key] = undefined
this.swipe(this.footLink.pre)
this.len--
}
}
class LRUCache {
private capacity = 0
private linkMap: LinkMap
constructor(capacity: number) {
this.capacity = capacity
this.linkMap = new LinkMap()
}
get(key: number): number {
if (!this.linkMap.has(key)) {
return -1
}
const node = this.linkMap.get(key)
this.linkMap.moveToHead(node)
return node.val
}
put(key: number, value: number): void {
this.linkMap.set(key, value)
while (this.linkMap.size() > this.capacity) {
this.linkMap.deleteLast()
}
}
}
```