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()
返回 除去 死亡人员的当前继承顺序列表。
示例
解题思路
birth函数表示将一个节点加入继承顺序中,death函数表示将一个节点标记为死亡状态。死亡节点不影响孩子节点的继承顺序。
getInheritanceOrder函数表示返回当前继承顺序列表。
由题意可知,王位继承人的顺序从国王开始,然后是国王的子节点,然后是子节点的子节点,依次类推。
可以从国王节点开始前序遍历,遍历过程中将遍历到的节点(未被标记为死亡状态)放入一个数组中,最后返回这个数组即可。
java
class ThroneInheritance {
Map<String, List<String>> edges;
Set<String> death;
List<String> ret;
String king;
public ThroneInheritance(String kingName) {
edges = new HashMap<>();
death = new HashSet<>();
king = kingName;
}
public void birth(String parentName, String childName) {
List<String> children = edges.getOrDefault(parentName, new ArrayList());
children.add(childName);
edges.put(parentName, children);
}
public void death(String name) {
death.add(name);
}
public List<String> getInheritanceOrder() {
ret = new ArrayList<>();
preOrder(king);
return ret;
}
void preOrder(String name) {
if (!death.contains(name)) {
ret.add(name);
}
List<String> children = edges.getOrDefault(name, new ArrayList());
for(String childName : children) {
preOrder(childName);
}
}
}
kotlin
class ThroneInheritance(kingName: String) {
val edges by lazy {
mutableMapOf<String, MutableList<String>>()
}
val death by lazy {
HashSet<String>()
}
var ret: MutableList<String>? = null
val king = kingName
fun birth(parentName: String, childName: String) {
val children = edges.getOrDefault(parentName, mutableListOf<String>())
children.add(childName)
edges.put(parentName, children)
}
fun death(name: String) {
death.add(name)
}
fun getInheritanceOrder(): List<String> {
ret = mutableListOf<String>()
preOrder(king)
return ret ?: mutableListOf<String>()
}
fun preOrder(name: String) {
if (!death.contains(name)) {
ret?.add(name)
}
edges[name]?.forEach {
preOrder(it)
}
}
}
go
type ThroneInheritance struct {
edges map[string][]string
death map[string]bool
king string
}
func Constructor(kingName string) ThroneInheritance {
return ThroneInheritance{
edges: map[string][]string{},
death: map[string]bool{},
king: kingName,
}
}
func (this *ThroneInheritance) Birth(parentName string, childName string) {
this.edges[parentName] = append(this.edges[parentName], childName)
}
func (this *ThroneInheritance) Death(name string) {
this.death[name] = true
}
func (this *ThroneInheritance) GetInheritanceOrder() []string {
var ret []string
var preorder func(string)
preorder = func(name string) {
if (!this.death[name]) {
ret = append(ret, name)
}
for _, childName := range this.edges[name] {
preorder(childName)
}
}
preorder(this.king)
return ret
}