一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。
编程世界总是离不了算法
最近在看框架源码时,会有很多算法的实现逻辑,有时候会感到吃力
于是决定蹭着假期,加强算法和数据结构相关的知识
那怎么提升呢?
其实我知道算法这东西没有捷径,多写多练才能提升,于是我开启我的LeetCode
刷题之旅
第一阶段目标是:200
道,每天1
到2
篇
为了不乱,本系列文章目录分为三部分:
- 今日题目:xxx
- 我的思路
- 代码实现
进入题目:380. O(1) 时间插入、删除和获取随机元素
实现RandomizedSet 类:
- RandomizedSet() 初始化 RandomizedSet 对象
- bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false 。
- bool remove(int val) 当元素 val 存在时,从集合中移除该项,并返回 true ;否则,返回 false 。
- int getRandom() 随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。 你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1) 。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/in… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的思路
如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop 掉。交换两个元素必须通过索引进行交换,那么我们需要一个哈希表 valToIndex 来记录每个元素值对应的索引。
代码实现
var RandomizedSet = function() {
this.valToIndex = new Map();
this.nums = [];
};
/**
* @param {number} val
* @return {boolean}
*/
RandomizedSet.prototype.insert = function(val) {
if (this.valToIndex.has(val)) {
return false;
}
// 假设第一次push,nums的length为0
// 就相当于往map里记录此时的val的index为0
this.valToIndex.set(val, this.nums.length);
this.nums.push(val);
return true;
};
/**
* @param {number} val
* @return {boolean}
*/
RandomizedSet.prototype.remove = function(val) {
if (!this.valToIndex.has(val)) {
return false;
}
let index = this.valToIndex.get(val);
// 如果要remove的元素正好是数组最后一个
if (index === this.nums.length - 1) {
this.valToIndex.delete(val);
this.nums.pop();
}else {
let lastVal = this.nums.pop();
this.nums[index] = lastVal;
this.valToIndex.set(lastVal, index);
this.valToIndex.delete(val);
}
return true;
};
/**
* @return {number}
*/
RandomizedSet.prototype.getRandom = function() {
let p = parseInt(Math.random() * this.nums.length);
return this.nums[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()
*/
总结
实现方式其实有很多,这里仅供参考~
由于刚开始刷题,也不知道从哪里刷好,如果前辈们有好的建议,希望不吝赐教,感谢🌹