【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 组成。

  1. 一开始, curOrder ["king"].
  2. 调用 Successor(king, curOrder) ,返回 Alice ,所以我们将 Alice 放入 curOrder 中,得到 ["king", "Alice"]
  3. 调用 Successor(Alice, curOrder) ,返回 Jack ,所以我们将 Jack 放入 curOrder 中,得到 ["king", "Alice", "Jack"]
  4. 调用 Successor(Jack, curOrder) ,返回 Bob ,所以我们将 Bob 放入 curOrder 中,得到 ["king", "Alice", "Jack", "Bob"]
  5. 调用 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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值