倍增,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);
 */
相关推荐
xiaoshiguang32 小时前
LeetCode:222.完全二叉树节点的数量
算法·leetcode
爱吃西瓜的小菜鸡2 小时前
【C语言】判断回文
c语言·学习·算法
别NULL2 小时前
机试题——疯长的草
数据结构·c++·算法
TT哇2 小时前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
ZSYP-S4 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos4 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习4 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA4 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo4 小时前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc4 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法