【Leetcode刷题记录_C++】【更加复杂的数据结构】

更加复杂的数据结构

并查集

并查集(union-find, 或 disjoint set)可以动态地连通两个点,并且可以非常快速地判断两个点是否连通。假设存在 n 个节点,我们先将所有节点的父亲标为自己;每次要连接节点 i 和 j 时,我们可以将 i 的父亲标为 j;每次要查询两个节点是否相连时,我们可以查找 i 和 j 的祖先是否最终为同一个人。

684. 冗余连接

树可以看成是一个连通且 无环 的 无向 图。

给定往一棵 n 个节点 (节点值 1~n) 的树中添加一条边后的图。添加的边的两个顶点包含在 1 到 n 中间,且这条附加的边不属于树中已存在的边。图的信息记录于长度为 n 的二维数组 edges ,edges[i] = [ai, bi] 表示图中在 ai 和 bi 之间存在一条边。

请找出一条可以删去的边,删除后可使得剩余部分是一个有着 n 个节点的树。如果有多个答案,则返回数组 edges 中最后出现的边。

思路:
需要判断是否两个节点被重复连通,所以我们可以使用并查集来解决此类问题
初始化一个容器vector,使得vector[i]=i,作为索引的i是指当前节点,作为值的i是指当前节点所在集合的代表节点
例:读取顺序为[[1,2], [3,4], [3,2], [1,4], [1,5]]
当前vector[0, 2, 2, 4, 2, 5]
当前index [0, 1, 2, 3, 4, 5]
从节点1出发,vector[1]=2, vector[2]=2, 找到节点1所在集合代表节点为2
从节点4出发,vector[4]=2, vector[2]=2, 找到节点4所在集合代表节点为2(往上追溯父节点,直到等于自身的,把它的父节点改掉,如果追溯以后发现两个端点追溯到的父节点等于自身的点相同,则返回)
由于1和4的代表节点相同,说明这两个节点本身就在同一个集合中
代码:

复合数据结构

146. LRU 缓存机制

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。

实现 LRUCache 类:

LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

进阶:你是否可以在 O(1) 时间复杂度内完成这两种操作?
思路:
使用哈希表进行定位,找出缓存项在双向链表中的位置,随后将其移动到双向链表的头部,即可在 O(1)的时间内完成 get 或者 put 操作。
代码:

练习

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

实现RandomizedSet 类:

RandomizedSet() 初始化 RandomizedSet 对象
bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false 。
bool remove(int val) 当元素 val 存在时,从集合中移除该项,并返回 true ;否则,返回 false 。
int getRandom() 随机返回现有集合中的一项(测试用例保证调用此方法时集合中至少存在一个元素)。每个元素应该有 相同的概率 被返回。

你必须实现类的所有函数,并满足每个函数的 平均 时间复杂度为 O(1) 。

思路:
哈希+动态数组,删除时和最后一个元素互换(哈希表只用改两次)
代码:

432. 全 O(1) 的数据结构

请你实现一个数据结构支持以下操作:

Inc(key) - 插入一个新的值为 1 的 key。或者使一个存在的 key 增加一,保证 key 不为空字符串。
Dec(key) - 如果这个 key 的值是 1,那么把他从数据结构中移除掉。否则使一个存在的 key 值减一。如果这个 key 不存在,这个函数不做任何事情。key 保证不为空字符串。
GetMaxKey() - 返回 key 中值最大的任意一个。如果没有元素存在,返回一个空字符串"" 。
GetMinKey() - 返回 key 中值最小的任意一个。如果没有元素存在,返回一个空字符串""。

挑战:

你能够以 O(1) 的时间复杂度实现所有操作吗?

思路:
哈希+双向链表,链表按value降序排列
三个哈希表,分别用于维护3个“node指针”:hash[key],对应key的node指针、hash1[value],对应value的第一个node指针、hash2[value],对应value的最后一个node指针。
插入时先查hash,再查hash2,删除时先查hash,再查hash1
代码:

716.最大栈

设计一个最大栈,支持 push、pop、top、peekMax 和 popMax 操作。
思路:
栈、最大栈(比当前最大的大才加入)、缓冲栈(popMax时使用)
代码:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ycr的帐号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值