LeetCode 721.账户合并 题解

题目信息

LeetoCode地址: 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目理解

原题使用的是名称和账号的邮箱地址,好多字母,可能有些人会不太好理解。我换了一种场景:联想一下,诸如《魔兽世界》《地下城与勇士》这样的网络游戏,每个玩家都可以创建多个游戏角色,每个游戏角色的ID都是服务器唯一的。注意,玩家的姓名在现实生活中是完全可以重复的。

在下图上半部分里,有一些玩家: 两位周小董, 两位张小涵,他们都拥有一些游戏角色。

按照题目的意思,因为两个周小董都拥有角色《战斗至死》,所以这两个周小董其实同一个人,他们的游戏角色是可以直接合并,属于同一个人的。

相反的,因为两位张小涵的游戏角色都不重复,所以这是两位重名的玩家,他们的游戏角色是不应该合并的。

综上,如下图下半部分所示,最终周小董合并之后有三个游戏角色,而两位张小涵的游戏角色保持不变。

图1
图1

由于玩家合并之后,一定没有两位玩家拥有相同的角色,所以可以得出结论,所有的角色ID都是独一无二的,而不像合并前有重复。

解题思路

数组并查集+哈希表

我们已经知道最终合并之后是不存在重复的角色ID的,找到它们并确定哪个游戏角色属于哪个玩家是很简单的,使用HashMap就可以做到。问题的关键在于如何找到相同玩家的不同角色ID,并将他们合并。

首先,我们先给所有第一次出现角色ID按照从0开始递增的方式编号. 可以看到,我们总共有0到5也就是6个不重复的角色ID.

图2

要合并它们,我们可以换个思考方式。那就是除了利用玩家名字之外,还有没有别的办法表示一批角色ID是属于同一个人的?实际是有的!我们可以使用每个玩家的第一个角色作为这一批角色的父亲,或者叫做根。如果用图表示,就类似下面这样:

图3

现在,让我们聚焦到根是《0.一往无前》和《3.逍遥自在》的这两个树状结构。

图4

显而易见的,它们都拥有相同的《1.战斗至死》这个角色ID。想要将他们合并,也就是让这两个树状结构拥有相同的根。由于我们是按照从左到右的顺序遍历的,所以左边这棵树合并到右边这棵树是最自然的结果。如何做?以《1.战斗至死》举例,我们让它的根的根,等于第二棵树的根的根。

很多人要迷惑了啊,什么根的根的根。一个一个来看。第一个根是上图左侧的《1.战斗至死》的根,也就是《0.一往无前》。第二个根是上图左侧的《0.一往无前》的根,是它自己。第三个根,也就是我们在便利第二个周小董的游戏角色时,遇到的重复元素《1.战斗至死》的根,也就是《3.逍遥自在》。至此,两棵树会合并完成了。

最终状态就是下图的状态。

图4

现在让我们看看剩下两棵树

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值