给我 O(1) 时间, 查找/删除任意的元素

今天又到了熟悉的刷题环节为了保持高效的刷题习惯,我会在这里尽量保持日更的状态。

今天是两道在前端方面可能不会特别会注意的东西:

  • 比如说: 你是否研究过 vuekeepalive 的源码去分析它具体是如何工作的?
  • 你对于前端的 set/map的使用是否自己的独到的见解呢?

我这里之前做过一份set/map相关的总结, 希望对大家有所帮助。

地址: set vs map 还有 object

146. LRU 缓存

image.png

实现思路: 这里的实现思路主要是采用: 借助于map去存储每一个key,vlaue;

get()去取、put()更新. 需要注意的是拿到最近不去使用到的key

this.cache.keys().next().value

代码实现:

/**
 * @param {number} capacity
 */
var LRUCache = function(capacity) {
    this.cache = new Map();
    this.capacity = capacity;
};

/** 
 * @param {number} key
 * @return {number}
 */
LRUCache.prototype.get = function(key) {
    if (this.cache.has(key)) {
        let temp = this.cache.get(key);
        this.cache.delete(key);
        this.cache.set(key, temp);
        return temp;
    }
    return -1;
};

/** 
 * @param {number} key 
 * @param {number} value
 * @return {void}
 */
LRUCache.prototype.put = function(key, value) {
    if (this.cache.has(key)) {
        this.cache.delete(key)
    // } else if (this.capacity >= this.cache.size) { // error
    } else if (this.cache.size >= this.capacity) {
        this.cache.delete(this.cache.keys().next().value)
    }
    return this.cache.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)
 */


复制代码
380. O(1)时间插入、删除和获取随机元素

image.png

实现思路:数组+map的为主题思路:

  • 对于插入的实现其实就是可以通过数组的方式放在最后
  • 对于删除的实现要求的是 O(1) 那么我们需要一个结构去记录当前插入值的索引,这里推荐map, 以 value: index的格式存储;当我们要删除的时候需要根据当前的值找到对应的索引,先删掉索引, 然后和数组的最后一个元素交换, 再删除掉值; 最后就是最后一个元素覆盖掉当前删除值的位置,更新数组长度。
  • 对于获取的实现 会相对简单一些,根据 随机 * 数组长度 根据index去直接获取

代码实现:

var RandomizedSet = function() {
    this.num = [];
    this.map = new Map();
};

/** 
 * @param {number} val
 * @return {boolean}
 */
RandomizedSet.prototype.insert = function(val) {
    if (this.map.has(val)) return false;

    // index 从0 开始的
    this.map.set(val, this.num.length);
    this.num.push(val);
    return true;
};

/** 
 * @param {number} val
 * @return {boolean}
 */
RandomizedSet.prototype.remove = function(val) {
    // 这里是不存在 返回 false
    if (!this.map.has(val)) return false;

    let index = this.map.get(val);
    // 删除掉索引 map
    this.map.set(this.num[this.num.length-1], index);
    this.map.delete(val)
    // 删除掉值 num 
    this.num[index] = this.num[this.num.length-1];
    this.num.length--;
    return true;
};

/**
 * @return {number}
 */
RandomizedSet.prototype.getRandom = function() {
    let p = parseInt(Math.random() * this.num.length)
    return this.num[p];
};

/**
 * Your RandomizedSet object will be instantiated and called as such:
 * var obj = new RandomizedSet()
 * var param_1 = obj.insert(val)
 * var param_2 = obj.remove(val)
 * var param_3 = obj.getRandom()
 */

复制代码

另一种方法:

这种方式其实从代码的角度来说比较简单, 如果你对 Set结构比较熟悉的话,基本可以秒解这道题;我们可以直接来看代码的具体实现:

代码实现:



var RandomizedSet = function() {
    this.set = new Set();
};

/** 
 * @param {number} val
 * @return {boolean}
 */
RandomizedSet.prototype.insert = function(val) {
    if (this.set.has(val)) return false;

    this.set.add(val);
    return true;
};

/** 
 * @param {number} val
 * @return {boolean}
 */
RandomizedSet.prototype.remove = function(val) {
    if (!this.set.has(val)) return false;

    this.set.delete(val);
    return true;
};

/**
 * @return {number}
 */
RandomizedSet.prototype.getRandom = function() {
    let p  = parseInt(Math.random() * this.set.size);
    return [...this.set][p];
};

/**
 * Your RandomizedSet object will be instantiated and called as such:
 * var obj = new RandomizedSet()
 * var param_1 = obj.insert(val)
 * var param_2 = obj.remove(val)
 * var param_3 = obj.getRandom()
 */
复制代码

代码练习地址:

146. LRU 缓存

380. O(1)时间插入、删除和获取随机元素

Guess you like

Origin juejin.im/post/7062987353077317646