LeetCode-1600. 王位继承顺序【树 深度优先搜索 设计 哈希表】

LeetCode-1600. 王位继承顺序【树 深度优先搜索 设计 哈希表】

题目描述:

一个王国里住着国王、他的孩子们、他的孙子们等等。每一个时间点,这个家庭里有人出生也有人死亡。

这个王国有一个明确规定的王位继承顺序,第一继承人总是国王自己。我们定义递归函数 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() 返回 除去 死亡人员的当前继承顺序列表。

示例:

输入:

"ThroneInheritance", "birth", "birth", "birth", "birth", "birth", "birth", "getInheritanceOrder", "death", "getInheritanceOrder"

\["king"\], \["king", "andy"\], \["king", "bob"\], \["king", "catherine"\], \["andy", "matthew"\], \["bob", "alex"\], \["bob", "asha"\], \[null\], \["bob"\], \[null\]

输出:

null, null, null, null, null, null, null, \["king", "andy", "matthew", "bob", "alex", "asha", "catherine"\], null, \["king", "andy", "matthew", "alex", "asha", "catherine"\]

解释:

ThroneInheritance t= new ThroneInheritance("king"); // 继承顺序:king

t.birth("king", "andy"); // 继承顺序:king > andy

t.birth("king", "bob"); // 继承顺序:king > andy > bob

t.birth("king", "catherine"); // 继承顺序:king > andy > bob > catherine

t.birth("andy", "matthew"); // 继承顺序:king > andy > matthew > bob > catherine

t.birth("bob", "alex"); // 继承顺序:king > andy > matthew > bob > alex > catherine

t.birth("bob", "asha"); // 继承顺序:king > andy > matthew > bob > alex > asha > catherine

t.getInheritanceOrder(); // 返回 ["king", "andy", "matthew", "bob", "alex", "asha", "catherine"]

t.death("bob"); // 继承顺序:king > andy > matthew > bob(已经去世)> alex > asha > catherine

t.getInheritanceOrder(); // 返回 ["king", "andy", "matthew", "alex", "asha", "catherine"]

提示:

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 。

解题思路一:多叉树的前序遍历【深度优先搜索】

根据题目描述,我们可以发现,王位继承顺序实际上是一个多叉树的前序遍历。我们可以使用一个哈希表 g 存储每个人的孩子,使用一个集合 dead存储已经去世的人。

调用 birth(parentName, childName) 时,我们将 childName 添加到 parentName 的孩子列表中。

调用 death(name) 时,我们将 name 添加到 dead 集合中。

调用 getInheritanceOrder() 时,我们从国王开始进行深度优先搜索,如果当前节点 x 没有去世,我们将 x 添加到答案列表中,然后递归地遍历 x 的所有孩子。

python 复制代码
class ThroneInheritance:

    def __init__(self, kingName: str):
        self.king = kingName
        self.dead = set()
        self.g = defaultdict(list)

    def birth(self, parentName: str, childName: str) -> None:
        self.g[parentName].append(childName)

    def death(self, name: str) -> None:
        self.dead.add(name)

    def getInheritanceOrder(self) -> List[str]:
        def dfs(x: str):
            x not in self.dead and ans.append(x)
            for y in self.g[x]:
                dfs(y)

        ans = []
        dfs(self.king)
        return ans

# Your ThroneInheritance object will be instantiated and called as such:
# obj = ThroneInheritance(kingName)
# obj.birth(parentName,childName)
# obj.death(name)
# param_3 = obj.getInheritanceOrder()

birth 和 death 的时间复杂度均为 O(1),getInheritanceOrder 的时间复杂度为 O(n)

空间复杂度:O(n)

解题思路二:0

python 复制代码

时间复杂度:O(n)

空间复杂度:O(n)

解题思路三:0

python 复制代码

时间复杂度:O(n)

空间复杂度:O(n)

相关推荐
这就是编程22 分钟前
自回归模型的新浪潮?GPT-4o图像生成技术解析与未来展望
人工智能·算法·机器学习·数据挖掘·回归
羑悻的小杀马特25 分钟前
【狂热算法篇】探寻图论幽径:Bellman - Ford 算法的浪漫征程(通俗易懂版)
c++·算法·图论·bellman_ford算法
Fantasydg4 小时前
DAY 31 leetcode 142--链表.环形链表
算法·leetcode·链表
basketball6164 小时前
C++ STL常用算法之常用排序算法
c++·算法·排序算法
moz与京4 小时前
[附C++,JS,Python题解] Leetcode 面试150题(10)——轮转数组
c++·python·leetcode
qystca4 小时前
蓝桥云客 岛屿个数
算法·dfs·bfs
什码情况5 小时前
回文时间 - 携程机试真题题解
数据结构·python·算法·华为od·机试
lwewan6 小时前
26考研——栈、队列和数组_数组和特殊矩阵(3)
数据结构·笔记·考研·算法
拾零吖6 小时前
枚举算法-day2
数据结构·算法·leetcode
已经成为了代码的形状6 小时前
关于交换并查集内元素的一些题的做法
数据结构·算法