【LeetCode】1483. Kth Ancestor of a Tree Node 1483. 树节点的第 K 个祖先

1

由于O(N^2)的存储会超内存限制,所以直接记忆化肯定凉了。
只能考虑O(NlogN)的存储,方法就对每个node都记下,它k=1,2,4,8,…时候的k祖先。比如,可以用f[h][node]表示node2**h祖先是谁。

需要注意的是,记这个的时候也得做一些优化,直接暴力遍历还是会超时。原理就是:
node的 2 h 2^h 2h距离的祖先就是它 2 h − 1 2^{h-1} 2h1祖先的 2 h − 1 2^{h-1} 2h1祖先,f[h][node] = f[h-1][f[h-1][node]]

然后在query的时候,直接跳到最接近的那个位置h,使得 2 h < = k < 2 h + 1 2^h<=k<2^{h+1} 2h<=k<2h+1,然后找f[h][node] k − 2 h k-2^h k2h祖先即可。

时间复杂度:

  • constructor: O ( N l o g N ) O(NlogN) O(NlogN)
  • query: O ( Q l o g N ) O(QlogN) O(QlogN)
class TreeAncestor:

    def __init__(self, n: int, parent: List[int]):
        h = floor(log(n, 2))
        self.dist = [parent] + [[-1]*n for _ in range(h)]  # dist[i][j] = getKthAncestor(j, 2**i)
        
        for i in range(1, h+1):
            for j in range(n):
                m = self.dist[i-1][j]
                if m != -1:
                    self.dist[i][j] = self.dist[i-1][m]
        
        # print(self.dist)
            
    
    @lru_cache()
    def getKthAncestor(self, node: int, k: int) -> int:
        if node == -1:
            return -1
        h = floor(log(k, 2))
        if k > 2**h:
            return self.getKthAncestor(self.dist[h][node], k - 2**h)
        return self.dist[h][node]


# Your TreeAncestor object will be instantiated and called as such:
# obj = TreeAncestor(n, parent)
# param_1 = obj.getKthAncestor(node,k)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值