站长之家域名ip查询,怎么搭建一个小程序,江苏网站seo营销模板,用wordpress做博客代码训练(23)LeetCode之随机访问元素
Author: Once Day Date: 2025年6月5日
漫漫长路#xff0c;才刚刚开始…
全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客
参考文章:
380. O(1) 时间插入、删除和获取随机元素 - 力扣#xff08;LeetCode#xff09;力…代码训练(23)LeetCode之随机访问元素
Author: Once Day Date: 2025年6月5日
漫漫长路才刚刚开始…
全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客
参考文章:
380. O(1) 时间插入、删除和获取随机元素 - 力扣LeetCode力扣 (LeetCode) 全球极客挚爱的技术成长平台 文章目录 代码训练(23)LeetCode之随机访问元素1. 原题2. 分析3. 代码实现4. 总结 1. 原题 实现RandomizedSet 类 RandomizedSet() 初始化 RandomizedSet 对象bool insert(int val) 当元素 val 不存在时向集合中插入该项并返回 true 否则返回 false 。bool remove(int val) 当元素 val 存在时从集合中移除该项并返回 true 否则返回 false 。int getRandom() 随机返回现有集合中的一项测试用例保证调用此方法时集合中至少存在一个元素。每个元素应该有 相同的概率 被返回。 你必须实现类的所有函数并满足每个函数的 平均 时间复杂度为 O(1) 。 提示 -231 val 231 - 1最多调用 insert、remove 和 getRandom 函数 2 * 105 次在调用 getRandom 方法时数据结构中 至少存在一个 元素。 示例 1
输入
[RandomizedSet, insert, remove, insert, getRandom, remove, insert, getRandom]
[[], [1], [2], [2], [], [1], [2], []]
输出
[null, true, false, true, 2, true, false, 2]解释
RandomizedSet randomizedSet new RandomizedSet();
randomizedSet.insert(1); // 向集合中插入 1 。返回 true 表示 1 被成功地插入。
randomizedSet.remove(2); // 返回 false 表示集合中不存在 2 。
randomizedSet.insert(2); // 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。
randomizedSet.getRandom(); // getRandom 应随机返回 1 或 2 。
randomizedSet.remove(1); // 从集合中移除 1 返回 true 。集合现在包含 [2] 。
randomizedSet.insert(2); // 2 已在集合中所以返回 false 。
randomizedSet.getRandom(); // 由于 2 是集合中唯一的数字getRandom 总是返回 2 。2. 分析
题目要求实现一个 RandomizedSet 类该类包含以下方法
RandomizedSet() - 初始化对象。bool insert(int val) - 插入元素 val如果元素不存在则插入并返回 true否则返回 false。bool remove(int val) - 移除元素 val如果元素存在则移除并返回 true否则返回 false。int getRandom() - 随机返回集合中的一个元素。保证调用时集合中至少有一个元素且每个元素有相同的被返回概率。
要求所有操作的平均时间复杂度为 O(1)。
为了满足该题目的要求我们可以使用哈希表和数组组合的数据结构
数组用于存储元素支持 O(1) 时间复杂度的随机访问。哈希表键为元素值值为该元素在数组中的索引支持 O(1) 时间复杂度的插入和删除操作。
方法实现细节
插入 (insert):
检查哈希表中是否已存在该元素。如果存在返回 false。将元素添加到数组末尾并在哈希表中记录该元素的索引。返回 true。
删除 (remove):
检查哈希表中是否存在该元素。如果不存在返回 false。从数组中移除该元素为了维持 O(1) 的复杂度可以将数组最后一个元素移动到被删除元素的位置并更新哈希表。从哈希表中删除该元素并更新数组的大小。返回 true。
获取随机元素 (getRandom):
从数组中随机选择一个索引然后返回该索引对应的元素。
性能优化关键点:
内存管理合理分配和释放内存是关键尤其是在 randomizedSetCreate 和 randomizedSetFree 函数中。哈希冲突避免哈希冲突可以提升性能因此选择合适的哈希函数和冲突解决机制很重要。
3. 代码实现
struct entry {int val;int idx;struct entry* next;
};typedef struct {int size; // 当前元素数量int array[200000]; // 动态数组存储元素struct entry* map[100000]; // 哈希表存储元素到索引的映射
} RandomizedSet;RandomizedSet* randomizedSetCreate() {RandomizedSet* set malloc(sizeof(RandomizedSet));memset(set, 0x0, sizeof(RandomizedSet));srand(time(NULL)); // 初始化随机种子return set;
}bool randomizedSetInsert(RandomizedSet* set, int val) {int key val % 100000;struct entry** prev (set-map[key]);struct entry* item set-map[key];while (item ! NULL) {if (item-val val) {return false;}prev (item-next);item item-next;}item malloc(sizeof(struct entry));item-val val;item-next NULL;item-idx set-size;*prev item;set-array[set-size] val;set-size;return true;
}bool randomizedSetRemove(RandomizedSet* set, int val) {int key val % 100000;struct entry** prev (set-map[key]);struct entry* item set-map[key];while (item ! NULL) {if (item-val val) {break;}prev (item-next);item item-next;}if (item NULL) {return false;}*prev item-next;int idx item-idx;free(item);if (idx set-size - 1) {set-size--;return true;}int lastElement set-array[set-size - 1];set-array[idx] lastElement; // 将最后一个元素移动到被删除元素的位置set-size--;key lastElement % 100000;item set-map[key];while (item ! NULL) {if (item-val lastElement) {break;}item item-next;}item-idx idx;return true;
}int randomizedSetGetRandom(RandomizedSet* set) {int randomIndex rand() % set-size;return set-array[randomIndex];
}void randomizedSetFree(RandomizedSet* set) {for (int i 0; i 100000; i) {struct entry* item set-map[i];while (item ! NULL) {struct entry* temp item-next;free(item);item temp;}}free(set);
}这段代码实现了一个 RandomizedSet 结构它支持插入、删除、随机访问和销毁操作。下面分析每部分代码的功能和设计逻辑。
使用了两种数据结构
数组 (array)用于存储元素值支持快速通过索引访问和随机访问。哈希表 (map)链地址法解决哈希冲突的哈希表存储键为元素值值为该元素在数组中的索引。
分配内存并初始化 RandomizedSet其中 memset 用于初始化内存区域。
插入操作首先计算哈希键值然后遍历链表检查元素是否已存在。如果不存在创建新条目并加入链表和数组。
删除操作查找链表中的元素然后从链表和数组中删除同时更新相关元素的索引。
通过随机生成索引来从数组中获取元素。
释放哈希表中所有链表的内存以及 RandomizedSet 结构的内存。
4. 总结
这个题目主要考察数据结构的灵活应用和操作的优化。通过综合利用数组和哈希表我们能够实现各种操作的平均 O(1) 时间复杂度。对于提升编程能力重点是掌握各种数据结构的特点及其适用场景以及如何根据需求选择和设计最合适的数据结构。
表和数组中删除同时更新相关元素的索引。
通过随机生成索引来从数组中获取元素。
释放哈希表中所有链表的内存以及 RandomizedSet 结构的内存。