LC每日一题|20240406 - 1483. 树节点的第 K 个祖先

80 阅读1分钟

1483. 树节点的第 K 个祖先

给你一棵树,树上有 n 个节点,按从 0n-1 编号。树以父节点数组的形式给出,其中 parent[i] 是节点 i 的父节点。树的根节点是编号为 0 的节点。

树节点的第 k 个祖先节点是从该节点到根节点路径上的第 k 个节点。

实现 TreeAncestor 类:

  • TreeAncestor(int n, int[] parent) 对树和父数组中的节点数初始化对象。
  • getKthAncestor``(int node, int k) 返回节点 node 的第 k 个祖先节点。如果不存在这样的祖先节点,返回 -1 。

提示:

  • 1 <= k <= n <= 5 * 10^4
  • parent[0] == -1 表示编号为 0 的节点是根节点。
  • 对于所有的 0 < i < n0 <= parent[i] < n 总成立
  • 0 <= node < n
  • 至多查询 5 * 10^4

题目等级:hard

我早就有预感今天会是hard...

尝试自己手扫了一遍,果不其然的TLE了,然后乖乖滚去看题解了...

class TreeAncestor(n: Int, val parent: IntArray) {
    val ancestors = Array<IntArray>(n) { IntArray(16) { -1 } }
    init {
        for (i in 0 until n) { ancestors[i][0] = parent[i]}
        for (i in 1 until 16) for (j in 0 until n) {
            if (ancestors[j][i - 1] != -1) ancestors[j][i] = ancestors[ancestors[j][i - 1]][i - 1]
        }
    }
    fun getKthAncestor(node: Int, k: Int): Int {
        var cur = node
        for (i in 0 until 16) {
            if ((k shr i) and 1 != 0) {
                cur = ancestors[cur][i]
                if (cur == -1) return cur
            }
        }
        return cur
    }
}


/**
 * Your TreeAncestor object will be instantiated and called as such:
 * var obj = TreeAncestor(n, parent)
 * var param_1 = obj.getKthAncestor(node,k)
 */

涉及到的知识点:倍增 OI-Wiki