lc380——数据结构好题

Posted hans774882968

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lc380——数据结构好题相关的知识,希望对你有一定的参考价值。

传送门

需要等概率返回随机元素,自然是用数组比较好,用哈希表不太方便。但insert需要判定元素是否存在,用数组不方便,用哈希表就比较好。

难道我们要二选一吗?小孩才做选择,大人表示:我全都要

我们不妨既维护数组又维护哈希表。于是我们只需要解决remove的问题,但remove就变得更困难了。O(1)删除哈希表也是容易的,但如何O(1)删除数组呢?我们注意到,哈希表的value存储的属性还没用上。因为题意保证值是unique的,所以我们不妨记录每个值在数组中的下标。于是我们知道了待删除元素v的下标idx = mp[v]

我们知道,数组可以直接当作栈来使用,删除栈顶的复杂度是O(1)的,因此我们不妨把a[idx]a.back()交换,然后a.pop()。这样remove的问题就圆满解决了。

我们在remove的时候,需要注意:

  • a.back()移动到了idx的位置,因此哈希表也要做出对应的同步。
  • idx+1 == a.size()的情况是存在的,为了避免对这种情况进行特殊讨论,我们不妨先修改哈希表,再对哈希表进行删除操作。

代码

"use strict";
//node lc380-AC.js

var RandomizedSet = function() {
  this.a = []
  this.idx = new Map()
};

RandomizedSet.prototype.insert = function(v) {
  if (this.idx.has(v)) return false
  this.a.push(v)
  this.idx.set(v, this.a.length - 1)
  return true
};

RandomizedSet.prototype.remove = function(v) {
  if (!this.idx.has(v)) return false
  const idx = this.idx.get(v), u = this.a[this.a.length - 1]
  this.a[idx] = u
  this.a.pop()
  this.idx.set(u, idx)
  this.idx.delete(v)// 先set再删,避免分类讨论
  return true
};

RandomizedSet.prototype.getRandom = function() {
  return this.a[Math.floor(Math.random() * this.a.length)]
};

以上是关于lc380——数据结构好题的主要内容,如果未能解决你的问题,请参考以下文章

[H二分] lc1889. 装包裹的最小浪费空间(二分+思维+好题+周赛244_4)

[Hbfs] lc815. 公交路线(建图+多源bfs+bfs最短路+思维+好题)

[M背包] lc474. 一和零(二维费用背包+好题)

[M二分] lc1818. 绝对差值和(二分+贪心失败+好题)

[M前缀和] lc560. 和为K的子数组(经典好题+哈希优化)

lc1977-好题赏析:lcp(最长公共前缀)优化dp