题目:
一个王国里住着国王、他的孩子们、他的孙子们等等。每一个时间点,这个家庭里有人出生也有人死亡。
这个王国有一个明确规定的王位继承顺序,第一继承人总是国王自己。我们定义递归函数 Successor(x, curOrder)
,给定一个人 x
和当前的继承顺序,该函数返回 x
的下一继承人。
Successor(x, curOrder): 如果 x 没有孩子或者所有 x 的孩子都在 curOrder 中: 如果 x 是国王,那么返回 null 否则,返回 Successor(x 的父亲, curOrder) 否则,返回 x 不在 curOrder 中最年长的孩子
比方说,假设王国由国王,他的孩子 Alice 和 Bob (Alice 比 Bob 年长)和 Alice 的孩子 Jack 组成。
- 一开始,
curOrder
为["king"]
. - 调用
Successor(king, curOrder)
,返回 Alice ,所以我们将 Alice 放入curOrder
中,得到["king", "Alice"]
。 - 调用
Successor(Alice, curOrder)
,返回 Jack ,所以我们将 Jack 放入curOrder
中,得到["king", "Alice", "Jack"]
。 - 调用
Successor(Jack, curOrder)
,返回 Bob ,所以我们将 Bob 放入curOrder
中,得到["king", "Alice", "Jack", "Bob"]
。 - 调用
Successor(Bob, curOrder)
,返回null
。最终得到继承顺序为["king", "Alice", "Jack", "Bob"]
。
通过以上的函数,我们总是能得到一个唯一的继承顺序。
请你实现 ThroneInheritance
类:
ThroneInheritance(string kingName)
初始化一个ThroneInheritance
类的对象。国王的名字作为构造函数的参数传入。void birth(string parentName, string childName)
表示parentName
新拥有了一个名为childName
的孩子。void death(string name)
表示名为name
的人死亡。一个人的死亡不会影响Successor
函数,也不会影响当前的继承顺序。你可以只将这个人标记为死亡状态。string[] getInheritanceOrder()
返回 除去 死亡人员的当前继承顺序列表。
提示:
1 <= kingName.length, parentName.length, childName.length, name.length <= 15
kingName
,parentName
,childName
和name
仅包含小写英文字母。- 所有的参数
childName
和kingName
互不相同。 - 所有
death
函数中的死亡名字name
要么是国王,要么是已经出生了的人员名字。 - 每次调用
birth(parentName, childName)
时,测试用例都保证parentName
对应的人员是活着的。 - 最多调用
105
次birth
和death
。 - 最多调用
10
次getInheritanceOrder
。
思考:
分析题目中的递归函数Successor:
Successor(x, curOrder): 如果 x 没有孩子或者所有 x 的孩子都在 curOrder 中: 如果 x 是国王,那么返回 null 否则,返回 Successor(x 的父亲, curOrder) 否则,返回 x 不在 curOrder 中最年长的孩子
也就是说,继承列表最初为[国王],然后将国王的长子加入继承列表,然后将长子的长子加入继承列表......直到当前继承人没有孩子或者已经把所有孩子加入到继承列表了为止,然后将当前继承人的相邻的下一个兄弟加入继承列表,再重复以上加入长子的操作。
可以看出,以上操作类似于树的深度优先搜索中的前序遍历,因此我们定义一个函数,对整个家族的父子关系树进行前序遍历,用继承列表存储遍历到的人名。
因此,需要记录每个人的儿子和每个人是否存活,这里使用字典存储这两个关系,可以减少时间。
代码如下:
class ThroneInheritance(object):
def __init__(self, kingName):
"""
:type kingName: str
"""
self.kingName = kingName
self.child_dict = {kingName:[]} # 孩子字典存储每个人的孩子
self.alive_dict = {kingName:1} # 存活字典存储每个人的生死状态,1表示活着,0表示死亡
def birth(self, parentName, childName):
"""
:type parentName: str
:type childName: str
:rtype: None
"""
if parentName not in self.child_dict:
self.child_dict[parentName] = []
self.child_dict[parentName].append(childName) # 向孩子字典中加入父子关系
self.alive_dict[childName] = 1 # 向生死字典中加入新生儿的存活状态
def death(self, name):
"""
:type name: str
:rtype: None
"""
self.alive_dict[name] = 0 # 在生死字典中将死人的状态设为死亡(0)
def getInheritanceOrder(self):
"""
:rtype: List[str]
"""
kingName = self.kingName
child_dict = self.child_dict
alive_dict = self.alive_dict
curOrder = [] # 初始化继承顺序列表
def dfs(person):
if alive_dict[person] == 1: # 若此人活着,加入继承列表
curOrder.append(person)
for child in self.child_dict.get(person, []):
# 遍历这个人的所有孩子,使用get()方法避免访问字典中不存在的键导致错误
dfs(child)
dfs(kingName) # 从国王开始进行深度优先搜索
return curOrder
# Your ThroneInheritance object will be instantiated and called as such:
# obj = ThroneInheritance(kingName)
# obj.birth(parentName,childName)
# obj.death(name)
# param_3 = obj.getInheritanceOrder()
提交通过: