力扣刷题:有时间限制的缓存

256 阅读2分钟

前言:锻炼自己的思想,规范自己的编程思路。

问题:

编写一个类,它允许获取和设置键-值对,并且每个键都有一个 过期时间 。

该类有三个公共方法:

set(key, value, duration) :接收参数为整型键 key 、整型值 value 和以毫秒为单位的持续时间 duration 。一旦 duration 到期后,这个键就无法访问。如果相同的未过期键已经存在,该方法将返回 true ,否则返回 false 。如果该键已经存在,则它的值和持续时间都应该被覆盖。

get(key) :如果存在一个未过期的键,它应该返回这个键相关的值。否则返回 -1 。

count() :返回未过期键的总数。

示例:(放代码里面)

输入: 
["TimeLimitedCache", "set", "get", "count", "get"]
[[], [1, 42, 100], [1], [], [1]]
[0, 0, 50, 50, 150]
输出: [null, false, 42, 1, -1]
解释:
在 t=0 时,缓存被构造。
在 t=0 时,添加一个键值对 (1: 42) ,过期时间为 100ms 。因为该值不存在,因此返回false。
在 t=50 时,请求 key=1 并返回值 42。
在 t=50 时,调用 count() ,缓存中有一个未过期的键。
在 t=100 时,key=1 到期。
在 t=150 时,调用 get(1) ,返回 -1,因为缓存是空的。

思路:

函数名为 TimeLimitedCache,它可以用来创建具有时间限制的缓存对象。

TimeLimitedCache 构造函数定义了两个属性:map 和 times。map 是一个 Map 对象,用于存储缓存中的键值对。times 是一个对象,用于存储每个键的过期时间。

TimeLimitedCache 原型上定义了三个方法:set、get 和count。

  • set 方法接受三个参数:一个键key、一个值 value 和一个过期时间 duration(以毫秒为单位)。该方法首先检查缓存中是否已经存在给定的键。如果存在,则返回 true;否则返回 false。然后,它使用 set 方法将给定的键值对存储到map中。接下来,它使用 clearTimeout 方法清除之前为该键设置的过期时间(如果有的话)。最后,它使用 setTimeout 方法为该键设置一个新的过期时间,并将返回的定时器 ID 存储到 times 对象中。
  • get 方法接受一个键 key 作为参数。该方法使用 get 方法从 map中获取给定键对应的值。如果找到了这样的值,则返回它;否则返回 -1。
  • count 方法不接受任何参数。该方法返回缓存中未过期键的数量。它通过获取 map.size 属性来实现。

基于上述思考,代码如下:

var TimeLimitedCache = function () {
    this.map = new Map()
    this.times = {}
};
/**
 * @param {number} key
 * @param {number} value
 * @param {number} time until expiration in ms
 * @return {boolean} if un-expired key already existed
 */
TimeLimitedCache.prototype.set = function (key, value, duration) {
    let res = this.map.has(key)
    this.map.set(key, value)
    clearTimeout(this.times[key])
    this.times[key] = setTimeout(() => {
        this.map.delete(key)
    }, duration)
    return res
};
/**
 * @param {number} key
 * @return {number} value associated with key
 */
TimeLimitedCache.prototype.get = function (key) {
    return this.map.get(key) ?? -1
};
/**
 * @return {number} count of non-expired keys
 */
TimeLimitedCache.prototype.count = function () {
    return this.map.size
};

执行结果如下图:

image-20230626162957809.png