首页 > 编程语言 >1483. Kth Ancestor of a Tree Node (Hard)

1483. Kth Ancestor of a Tree Node (Hard)

时间:2023-06-18 16:55:21浏览次数:54  
标签:Node node parent index int Hard Tree getKthAncestor dp

Description

1483. Kth Ancestor of a Tree Node (Hard) You are given a tree with n nodes numbered from 0 to n - 1 in the form of a parent array parent where parent[i] is the parent of ith node. The root of the tree is node 0. Find the kth ancestor of a given node.

The kth ancestor of a tree node is the kth node in the path from that node to the root node.

Implement the TreeAncestor class:

  • TreeAncestor(int n, int[] parent) Initializes the object with the number of nodes in the tree and the parent array.
  • int getKthAncestor(int node, int k) return the kth ancestor of the given node node. If there is no such ancestor, return -1.

Example 1:

Input
["TreeAncestor", "getKthAncestor", "getKthAncestor", "getKthAncestor"]
[[7, [-1, 0, 0, 1, 1, 2, 2]], [3, 1], [5, 2], [6, 3]]
Output
[null, 1, 0, -1]

Explanation
TreeAncestor treeAncestor = new TreeAncestor(7, [-1, 0, 0, 1, 1, 2, 2]);
treeAncestor.getKthAncestor(3, 1); // returns 1 which is the parent of 3
treeAncestor.getKthAncestor(5, 2); // returns 0 which is the grandparent of 5
treeAncestor.getKthAncestor(6, 3); // returns -1 because there is no such ancestor

Constraints:

  • 1 <= k <= n <= 5 * 10⁴
  • parent.length == n
  • parent[0] == -1
  • 0 <= parent[i] < n for all 0 < i < n
  • 0 <= node < n
  • There will be at most 5 * 10⁴ queries.

Solution

The simplistic notion entails gradually searching for the parent node, resulting in a time complexity of O(n). Therefore, the overall time complexity becomes O(n^2), leading to a potential TLE (Time Limit Exceeded). Thus, we need to devise a more efficient approach for finding the parent node with a lower time complexity of O(log n). This leads us to contemplate a binary-like strategy.

For instance, let's assume we need to find getKthAncestor(1, 8). We can first determine x = getKthAncestor(1, 4) and then compute getKthAncestor(x, 4). This approach bears resemblance to dynamic programming.

Let's define $dp[i][j]$ as the i-th node's ancestor at the $2^j$ position, where $dp[i][j] = dp[dp[i][j-1]][j]$ and $dp[i][0] = parent[i]$.

During initialization, we can initialize the $dp[i][j]$ array. Given that $1 \leq k \leq n \leq 5 * 10^4$, the first dimension of the $dp$ array should have a size of n, and the second dimension's size can be set to logk = 20. In the constructor, we compute the $dp[i][j]$ array, taking care to handle the case when $dp[i][j] = -1$.

In the getKthAncestor() function, we can employ bitwise operations to calculate the parent node: $pa = dp[pa][i]$, provided that $((1 << i) & k) \neq 0$. If we compute $pa = -1$, we simply return pa.

Code

class TreeAncestor {
  public:
    TreeAncestor(int n, vector<int> &parent) :
        cnt_(n), index_(0), dp(n) {
        int x = 0;
        for (int i = 0; i < parent.size(); ++i) {
            parent_.push_back(parent[i]);
        }
        for (int i = 0; i < cnt_; ++i) {
            for (int j = 0; j < logk; ++j) {
                dp[i].push_back(-1);
            }
        }
        for (int i = 0; i < cnt_; ++i) {
            dp[i][0] = parent_[i];
        }
        while (index_ < logk) {
            for (int i = 0; i < cnt_; ++i) {
                if (dp[i][index_] != -1) {
                    dp[i][index_ + 1] = dp[dp[i][index_]][index_];
                }
            }
            x *= 2;
            ++index_;
        }
    }
    int getKthAncestor(int node, int k) {
        int pa = node;
        for (int i = 0; (1 << i) <= k; ++i) {
            if (((1 << i) & k) != 0) {
                pa = dp[pa][i];
                if (pa == -1) {
                    return pa;
                }
            }
        }
        return pa;
    }

  private:
    int cnt_;
    vector<int> parent_;
    int index_;
    vector<vector<int>> dp;
    const int logk = 20;
};

标签:Node,node,parent,index,int,Hard,Tree,getKthAncestor,dp
From: https://www.cnblogs.com/zwyyy456/p/17489332.html

相关文章

  • odoo16里面修改tree视图样式
    一、在static文件夹下新建一个css文件夹并将*.css文件写入/*该文件用来定义视图中的一些格式,需要用到的地方直接在xml文件中进行引用*//*语法说明*//*tableth:nth-child(1)代表定位到table的th上面到第一个th标题nth-child()参考css语法http://www.w3school.com.cn/c......
  • TreeSet
    TreeSet的使用下面是TreeSet的方法使用,代码实现如下:publicstaticvoidmain(String[]args){ TreeSet<String>set=newTreeSet<>(); //添加元素 set.add("小希"); set.add("小空"); set.add("小丽"); set.add("小光"); //获取元素......
  • sourceTree下载安装以及使用
    下载官网1.滑动到官网最底下找到Downloadarchive (所有版本) 2.windows电脑就下windows的版本(mac系统同理),下载3.4.13就开始下软件了  3.开始安装---一直点下一步就OK啦 具体使用:1.点击+或者暂存所有,实际上是执行了gitaddREADME.md命令:2.点击提交就完成了......
  • rawNode的成员变更用例
    【用例内容】 【主要逻辑】applyConfChange的时候1)通过之前的changer类做检查2)替换cfg和prs为新的值......
  • NodeJS系列(2)- 在 NPM 项目里使用 ECMAScript 6 (ES6) 规范
    NPM(NodePackageManager),NodeJS包或模块管理工具,比较新的NodeJS版本一般内置NPM。NPM有点类似于Maven在Java开发中的作用,NPM项目也和Maven项目类似,包含了创建、编译、运行、打包、部署等功能。ECMAScript6(ES6)是最新的JavaScript语言的标准化规范,它的目标是......
  •  SourceTree安装说明
    SourceTree安装之后需要使用账号登陆以授权,以前是可以不登陆的,但是现在是强制登陆。虽然是免费授权,但是碰上不可抗力因素,登陆不是很方便,这里记录一下跳过这个初始化的步骤。先运行一次安装包,出现需要登录的窗口后退出。此时桌面上就以出现快捷方式,不需要再使用安装文件了。安装之......
  • 智能合约HardHat框架环境的搭建
    1.首先创建一个npm项目PSC:\Users\lcds\blockchainprojects>mkdirhardhatcontractPSC:\Users\lcds\blockchainprojects>cd.\hardhatcontract\2.运行 npminit-y  初始化项目PSC:\Users\lcds\blockchainprojects\hardhatcontract>npminit-yWrotetoC:\......
  • centos8使用Yum安装nodejs步骤方法、nodejs升级切换版本的方法
    先确认系统是否已经安装了epel-release包(EPEL是企业版Linux的额外软件包,是Fedora小组维护的一个软件仓库项目,为RHEL/CentOS提供他们默认不提供的软件包。):Bash#yuminfoepel-release如果有输出有关epel-release的已安装信息,则说明已经安装,如果提示没有安装或可安装,则安装......
  • 安装的sourcetree打不开,点击以后就弹了下标标就没反应了
    到这个路径下C:\Users\sxws8\AppData\Local\Atlassiansxws8:这个根据你自己的路径来把这个删了就可以打开了。 ......
  • Node.js 开发常用到的库和插件工具,同事看到后也悄悄收藏了……
    Node.js是一个功能强大,并且非常流行的JavaScript运行时环境,使开发人员能够高效率的构建高性能应用程序。下面介绍了8个常见的应用程序开发中用到的库和函数,可以用于缓存数据、操作日期、处理图像、发送电子邮件、发出HTTP请求、记录请求和响应、压缩数据和哈希密码等。通过使......