LeetCode-1483. 树节点的第 K 个祖先

原题链接:LeetCode-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

方法一

p a [ x ] [ i ] pa[x][i] pa[x][i]代表着第 x x x节点的第 2 i 2^i 2i个父节点的序号,即 x x x 2 i + 1 2^{i+1} 2i+1个父节点等于 x x x的第 2 i 2^i 2i个父节点的第 2 i 2^i 2i个父节点,以此类推。
p a [ x ] [ i + 1 ] = p a [ p a [ x ] [ i ] ] [ i ] pa[x][i+1]=pa[pa[x][i]][i] pa[x][i+1]=pa[pa[x][i]][i]

class TreeAncestor {
    private int[][] pa; // pa[x][i]: x节点的2^i个父节点


    public TreeAncestor(int n, int[] parent) {
        int m = 32 - Integer.numberOfLeadingZeros(n); // 二进制长度
        pa = new int[n][m];

        // init
        for (int i = 0; i < n; i++) {
            pa[i][0] = parent[i];
        }

        for (int i = 0; i < m - 1; i++) {
            for (int x = 0; x < n; x++) {
                int p = pa[x][i];
                pa[x][i + 1] = p < 0 ? -1 : pa[p][i];
            }
        }
    }

    public int getKthAncestor(int node, int k) {
        int m = 32 - Integer.numberOfLeadingZeros(k);
        for (int i = 0; i < m; i++) {
            if (((k >> i) & 1) > 0) {
                node = pa[node][i];
                if (node < 0) break;
            }
        }
        return node;
    }

    public int getKthAncestor2(int node, int k) {
        for (; k > 0 && node != -1; k &= k - 1) {
            node = pa[node][Integer.numberOfTrailingZeros(k)];
        }
        return node;
    }
}

参考资料

https://leetcode.cn/problems/kth-ancestor-of-a-tree-node/solutions/2305895/mo-ban-jiang-jie-shu-shang-bei-zeng-suan-v3rw

你可能感兴趣的:(LeetCode,leetcode,算法)