LeetCode 146题 LRU 缓存 (Least Recently Used 最近最少使用)(TS实现)

207 阅读3分钟

题目描述:

请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。

实现 LRUCache 类:

1.LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存

2.int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。

3.void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

4.函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

内容分析:

什么是LRU:最近最少使用。vue的keep-alive用的就是此算法核心

举个栗子:

我们有一段有明确空间大小的存储空间,最多只能存4个元素,当存储量小于4的时候,会按照顺序放入到存储空间内。例如:我们现有一块空的存储空间 [](此处并不表示前端的数组,仅仅为了描述方便)。

当我们来了第一个元素1的时候,因为长度小于不超过我们要求的4,所以我们放入空间中变为[1],同理又来2,3,4的时候,正常进入[4,3,2,1](最新进入的在最前面)。

如果在4个元素以内,出现相同元素,在把相同的元素放到我们空间的最前面,及若[3,2,1]再来一个1时或者2时,此时空间顺序变为[1,3,2]或者[2,3,1].

当元素满4个后,此时若在进来元素,在判断如果空间内已经存在,同上面一步把存在的元素放到第一位,及[4,3,2,1]时再来个1或2,空间内容变为[1,4,3,2]或[2,4,3,1]

如果此时进来的元素空间不存在,在把空间最后的元素删掉,把进来的元素放到最前面,及[4,3,2,1],此时来个5,空间内容变为[5,4,3,2]

整体来说,就是这段空间内,我每次都把进来次数(在开发中用的最少内容)放在空间最后,当超出限制时并且空间内没有这个元素时,把这个最后的元素挤掉,放入新的元素。有的话就变为这个元素又来(又被使用,增加了使用频率)了,则放入到空间最前面

代码:

class LRUCache {

    map:Map<any,any>
    capacity:number

    constructor(capacity: number) {
        this.map = new Map
        this.capacity = capacity
    }

    get(key: number): number {
       if(this.map.has(key)){
           const temp = this.map.get(key)
           this.map.delete(key)
           this.map.set(key,temp)
           return temp
       }
       return -1
    }

    put(key: number, value: number): void {
      if(this.map.has(key)){
          this.map.delete(key)
      }else if(this.map.size >= this.capacity){
          this.map.delete(this.map.keys().next().value)
      }
      this.map.set(key,value)
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * var obj = new LRUCache(capacity)
 * var param_1 = obj.get(key)
 * obj.put(key,value)
 */

思路讲解:

核心:Map这个数据结构的可以很好的帮助我们完成这项任务

1:我们新建一个变量capacity等于我们最大限制的数量,新建一个map用来存储和改变我们的内容

2:实现get()方法,当给定我们关键字key时我们要判读这个key是否在我们当前map中,如果不在,直接返回-1,当在的时候,我们通map.get(key)拿到这个key对应值,因为这个key又出现了一次,我们要把它放到我们存储的最前面,所以我们先用map.delete(key)删除这个内容,再借助map.set(key,value)把它放到最前面,最后返回这个key的值

3:实现put()方法。其实从使用map的本质上,一个内容信息要进来,如果map没有,我们直接插入,如果有,我们先删除,在插入,所以最后一定会走一步map.set(key,value)操作,因此我们只需判断当key已经存在,我们删除key(map.delete(key)),或者key不存在,我们删除最后一位元素map.delete(map.keys().next().value),最后在插入内容map.set(key,value)即可

4:针对map.keys().next().value使用的是迭代器原理,可以点击右侧链接查看: 迭代器