倍增,LeetCode 1483. 树节点的第 K 个祖先

目录

一、题目

1、题目描述

2、接口描述

python3

cpp

3、原题链接

二、解题报告

1、思路分析

2、复杂度

3、代码详解

python3

cpp


一、题目

1、题目描述

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

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

实现 TreeAncestor 类:

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

2、接口描述

python3
复制代码
python 复制代码
class TreeAncestor:

    def __init__(self, n: int, parent: List[int]):


    def getKthAncestor(self, node: int, k: int) -> int:



# Your TreeAncestor object will be instantiated and called as such:
# obj = TreeAncestor(n, parent)
# param_1 = obj.getKthAncestor(node,k)
cpp
复制代码
cpp 复制代码
class TreeAncestor {

  TreeAncestor(int n, List<int> parent) {
    
  }
  
  int getKthAncestor(int node, int k) {
    
  }
}

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

3、原题链接

1483. 树节点的第 K 个祖先


二、解题报告

1、思路分析

关于ST表求LCA见:LCA算法-倍增算法-CSDN博客

比ST表求LCA板子题还要简单的题

我们预处理出f[u][i],代表u向上跳2^i层的祖先

然后对于查询向上第k个祖先我们只需要将k二进制拆分往上跳即可

2、复杂度

时间复杂度: 预处理O(nlogn) 查询:O(k)空间复杂度:O(nlogn)

3、代码详解

python3
复制代码
python 复制代码
class TreeAncestor:

    def __init__(self, n: int, parent: List[int]):
        H = n.bit_length()
        fa = [[0] * H] + [[p + 1] + [0] * (H - 1) for p in parent]
        for i in range(1, H):
            for j in range(1, n + 1):
                fa[j][i] = fa[fa[j][i - 1]][i - 1]
        self.fa = fa

    def getKthAncestor(self, x: int, k: int) -> int:
        x += 1
        fa = self.fa
        for i in range(k.bit_length()):
            if k >> i & 1:
                x = fa[x][i]
        return x - 1


# Your TreeAncestor object will be instantiated and called as such:
# obj = TreeAncestor(n, parent)
# param_1 = obj.getKthAncestor(node,k)
cpp
复制代码
cpp 复制代码
const int N = 5e4 + 10, H = 16;
int fa[N][H];
class TreeAncestor {
public:
    TreeAncestor(int n, vector<int>& parent) {
        for(int i = 1; i < n; i++)
            fa[i + 1][0] = parent[i] + 1;
        for(int i = 1, ed = 32 - __builtin_clz(n); i < ed; i++)
            for(int j = 1; j <= n; j++)
                fa[j][i] = fa[fa[j][i - 1]][i - 1];
    }
    
    int getKthAncestor(int x, int k) {
        ++x;
        for(int i = 32 - __builtin_clz(k); i >= 0; i--)
            if(k >> i & 1)
                x = fa[x][i];
        return x - 1;
    }
};

/**
 * Your TreeAncestor object will be instantiated and called as such:
 * TreeAncestor* obj = new TreeAncestor(n, parent);
 * int param_1 = obj->getKthAncestor(node,k);
 */
相关推荐
workflower6 小时前
单元测试-例子
java·开发语言·算法·django·个人开发·结对编程
MicroTech20258 小时前
微算法科技(MLGO)研发突破性低复杂度CFG算法,成功缓解边缘分裂学习中的掉队者问题
科技·学习·算法
墨染点香8 小时前
LeetCode 刷题【126. 单词接龙 II】
算法·leetcode·职场和发展
aloha_7899 小时前
力扣hot100做题整理91-100
数据结构·算法·leetcode
Tiny番茄9 小时前
31.下一个排列
数据结构·python·算法·leetcode
挂科是不可能出现的9 小时前
最长连续序列
数据结构·c++·算法
_Aaron___9 小时前
List.subList() 返回值为什么不能强转成 ArrayList
数据结构·windows·list
前端小L10 小时前
动态规划的“数学之魂”:从DP推演到质因数分解——巧解「只有两个键的键盘」
算法·动态规划
RTC老炮10 小时前
webrtc弱网-ReceiveSideCongestionController类源码分析及算法原理
网络·算法·webrtc
21号 110 小时前
9.Redis 集群(重在理解)
数据库·redis·算法