一个王国里住着国王、他的孩子们、他的孙子们等等。每一个时间点,这个家庭里有人出生也有人死亡。
这个王国有一个明确规定的王位继承顺序,第一继承人总是国王自己。我们定义递归函数 Successor(x, curOrder) ,给定一个人 xx 的下一继承人。
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 <= 15kingName,parentName, childName 和 name 仅包含小写英文字母。所有的参数 childName 和 kingName  互不相同  。 
所有 death 函数中的死亡名字 name 要么是国王,要么是已经出生了的人员名字。 
每次调用 birth(parentName, childName) 时,测试用例都保证 parentName 对应的人员是活着的。 
最多调用 105 次birth 和 death 。 
最多调用 10 次 getInheritanceOrder 。 
 
方法一:多叉树的前序遍历 思路与算法 
我们可以发现,题目中定义的 Successor(x, curOrder) 函数,与多叉树的前序遍历过程是一致的:
「返回 x 不在 curOrder 中最年长的孩子」对应着选择 x 在树中的一个子节点,递归地进行遍历操作;
「返回 Successor(x} ~的父亲\texttt{, curOrder)」对应着当我们将以 x 为根的子树遍历完成后,回溯到 x 的父节点继续进行遍历;
「返回 null」对应着我们将整棵树遍历完成。
 
因此,对于题目中需要实现的每一个函数,我们可以分别设计出如下的算法:
ThroneInheritance(kingName):我们将 kingName 作为树的根节点;
birth(parentName, childName):我们在树中添加一条从 parentName 到 childName 的边,将 childName 作为 parentName 的子节点;
death(name):我们使用一个哈希集合记录所有的死亡人员,将 name 加入该哈希集合中;
getInheritanceOrder():我们从根节点开始对整棵树进行前序遍历。需要注意的是,如果遍历到死亡人员,那么不能将其加入继承顺序列表中 。
 
细节 
那么我们如何存储这棵树呢?
一种可行的方法是使用哈希映射。记哈希映射为 edges,那么对于 edges 中的每一个键值对 (k, v),键 k 表示一个人,值 v 以列表的形式存放了这个人所有的孩子,列表可以为空。
这样一来,对于 birth(parentName, childName) 操作,我们只需要将 childName 加入 parentName 在哈希映射中的列表末尾即可。
代码 
[sol1-C++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class  ThroneInheritance  {private :    unordered_map<string, vector<string>> edges;     unordered_set<string> dead;     string king; public :    ThroneInheritance (string kingName): king{move (kingName)} {}          void  birth (string parentName, string childName)           edges[move (parentName)].push_back (move (childName));     }          void  death (string name)           dead.insert (move (name));     }          vector<string> getInheritanceOrder ()   {         vector<string> ans;         function<void (const  string&)> preorder = [&](const  string& name) {             if  (!dead.count (name)) {                 ans.push_back (name);             }             if  (edges.count (name)) {                 for  (const  string& childName: edges[name]) {                     preorder (childName);                 }             }         };         preorder (king);         return  ans;     } }; 
[sol1-Java] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class  ThroneInheritance  {    Map<String, List<String>> edges;     Set<String> dead;     String king;     public  ThroneInheritance (String kingName)  {         edges = new  HashMap <String, List<String>>();         dead = new  HashSet <String>();         king = kingName;     }          public  void  birth (String parentName, String childName)  {         List<String> children = edges.getOrDefault(parentName, new  ArrayList <String>());         children.add(childName);         edges.put(parentName, children);     }          public  void  death (String name)  {         dead.add(name);     }          public  List<String> getInheritanceOrder ()  {         List<String> ans = new  ArrayList <String>();         preorder(ans, king);         return  ans;     }     private  void  preorder (List<String> ans, String name)  {         if  (!dead.contains(name)) {             ans.add(name);         }         List<String> children = edges.getOrDefault(name, new  ArrayList <String>());         for  (String childName : children) {             preorder(ans, childName);         }     } } 
[sol1-C#] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public  class  ThroneInheritance  {    Dictionary<string , IList<string >> edges;     ISet<string > dead;     string  king;     public  ThroneInheritance (string  kingName         edges = new  Dictionary<string , IList<string >>();         dead = new  HashSet<string >();         king = kingName;     }          public  void  Birth (string  parentName, string  childName         IList<string > children;         if  (edges.TryGetValue(parentName, out  children)) {             children.Add(childName);             edges[parentName] = children;         } else  {             children = new  List<string >();             children.Add(childName);             edges.Add(parentName, children);         }     }          public  void  Death (string  name         dead.Add(name);     }          public  IList<string > GetInheritanceOrder ()         IList<string > ans = new  List<string >();         Preorder(ans, king);         return  ans;     }     private  void  Preorder (IList<string > ans, string  name )         if  (!dead.Contains(name)) {             ans.Add(name);         }         IList<string > children = edges.TryGetValue(name, out  children) ? children : new  List<string >();         foreach  (string  childName in  children) {             Preorder(ans, childName);         }     } } 
[sol1-Python3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class  ThroneInheritance :    def  __init__ (self, kingName: str  ):         self.edges = defaultdict(list )         self.dead = set ()         self.king = kingName     def  birth (self, parentName: str , childName: str  ) -> None :         self.edges[parentName].append(childName)     def  death (self, name: str  ) -> None :         self.dead.add(name)     def  getInheritanceOrder (self ) -> List [str ]:         ans = list ()         def  preorder (name: str  ) -> None :             if  name not  in  self.dead:                 ans.append(name)             if  name in  self.edges:                 for  childName in  self.edges[name]:                     preorder(childName)         preorder(self.king)         return  ans 
[sol1-JavaScript] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 var  ThroneInheritance  = function (kingName ) {    this .edges  = new  Map ();     this .dead  = new  Set ();     this .king  = kingName; }; ThroneInheritance .prototype birth  = function (parentName, childName ) {    if  (!this .edges .has (parentName)) {         this .edges .set (parentName, []);     }     this .edges .get (parentName).push (childName); }; ThroneInheritance .prototype death  = function (name ) {    this .dead .add (name); }; ThroneInheritance .prototype getInheritanceOrder  = function (    const  ans = [];     const  preorder  = (name ) => {         if  (!this .dead .has (name)) {             ans.push (name);         }         if  (this .edges .has (name)) {             for  (const  childName of  this .edges .get (name)) {                 preorder (childName);             }         }     }     preorder (this .king );     return  ans; }; 
[sol1-Golang] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 type  ThroneInheritance struct  {    king  string      edges map [string ][]string      dead  map [string ]bool  } func  Constructor (kingName string )     return  ThroneInheritance{kingName, map [string ][]string {}, map [string ]bool {} } } func  (t *ThroneInheritance) string ) {    t.edges[parentName] = append (t.edges[parentName], childName) } func  (t *ThroneInheritance) string ) {    t.dead[name] = true  } func  (t *ThroneInheritance) string ) {    var  preorder func (string )      preorder = func (name string )          if  !t.dead[name] {             ans = append (ans, name)         }         for  _, childName := range  t.edges[name] {             preorder(childName)         }     }     preorder(t.king)     return  } 
复杂度分析 
时间复杂度:
ThroneInheritance(kingName):O(1);
birth(parentName, childName):O(1);
death(name):O(1);
getInheritanceOrder():O(n),其中 n 是当前树中的总人数。我们需要对整棵树进行一次前序遍历,时间复杂度为 O(n)。
 
空间复杂度:
n 个节点的树包含 n-1 条边,因此我们需要 O(n) 的空间(即哈希映射 edges)存储整棵树;
我们需要 O(n) 的空间(即哈希集合)存储所有的死亡人员;
在 getInheritanceOrder() 中前序遍历的过程中,我们使用的是递归,需要一定的栈空间,栈空间的大小与树的高度成正比。由于树的高度不会超过树中的节点个数,因此栈空间最多为 O(n)。
 
 
在上述的时空复杂度分析中,我们默认了所有字符串(即人名)的操作时间以及存储空间都是 O(1) 的。如果读者希望将字符串的长度也看作变量,那么只需要将除了栈空间以外的所有项由 O(1)/O(n) 变为 O(l)/O(nl) 即可,其中 l 是字符串的最大长度。