📌  相关文章
📜  二叉树中节点的第 K 个祖先 |设置 3(1)

📅  最后修改于: 2023-12-03 15:21:40.085000             🧑  作者: Mango

二叉树中节点的第 K 个祖先

在二叉树中,节点的祖先指的是从根节点到该节点的所有节点。而节点的第 K 个祖先则指的是从该节点往上数第 K 个节点。

给定一棵二叉树和一个节点,以及一个整数 K ,你需要找到这个节点的第 K 个祖先。

解法

思路

题目中要求找到一个节点的第 K 个祖先。根据题目的描述,我们可以使用递归的方法来求解,每次递归都要判断当前节点是否为目标节点,如果是,则返回 true。否则,我们继续递归左右子树。

在递归左右子树前,我们需要判断当前节点是否有左右子树。如果有,则分别对左右子树递归,如果左右子树返回 true,则在当前节点记录是否找到了目标节点。同时,在递归左右子树时,需要记录当前节点的父节点,便于在递归结束后,回溯进行第 K 个祖先的查找。

代码实现

我们先定义一个节点类,用于表示二叉树的节点和记录父节点。

class TreeNode:
    def __init__(self, val=0, left=None, right=None, parent=None):
        self.val = val
        self.left = left
        self.right = right
        self.parent = parent

接下来,我们实现递归函数 findAncestor(root, node, K, count),其中:

  • root 表示二叉树的根节点;
  • node 表示目标节点;
  • K 表示要查找的第 K 个祖先;
  • count 用于记录找到了多少个祖先。
def findAncestor(root, node, K, count):
    if not root:
        return False
    
    if root == node:
        return True
    
    # 递归左子树
    left = findAncestor(root.left, node, K, count)
    if left:
        count[0] += 1
        if count[0] == K:
            print(root.val)
            return True
    
    # 递归右子树
    right = findAncestor(root.right, node, K, count)
    if right:
        count[0] += 1
        if count[0] == K:
            print(root.val)
            return True
    
    return False

为了方便,我们再实现一个辅助函数 findNode(root, val),用于在二叉树中查找指定值的节点。

def findNode(root, val):
    if not root:
        return None
    
    if root.val == val:
        return root
    
    # 递归左子树
    left = findNode(root.left, val)
    if left:
        left.parent = root
        return left
    
    # 递归右子树
    right = findNode(root.right, val)
    if right:
        right.parent = root
        return right
    
    return None

最后,我们可以将上面的函数组合起来,实现完整的解决方案。

class TreeNode:
    def __init__(self, val=0, left=None, right=None, parent=None):
        self.val = val
        self.left = left
        self.right = right
        self.parent = parent


def findNode(root, val):
    if not root:
        return None
    
    if root.val == val:
        return root
    
    # 递归左子树
    left = findNode(root.left, val)
    if left:
        left.parent = root
        return left
    
    # 递归右子树
    right = findNode(root.right, val)
    if right:
        right.parent = root
        return right
    
    return None


def findAncestor(root, node, K, count):
    if not root:
        return False
    
    if root == node:
        return True
    
    # 递归左子树
    left = findAncestor(root.left, node, K, count)
    if left:
        count[0] += 1
        if count[0] == K:
            print(root.val)
            return True
    
    # 递归右子树
    right = findAncestor(root.right, node, K, count)
    if right:
        count[0] += 1
        if count[0] == K:
            print(root.val)
            return True
    
    return False


root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
root.right.left = TreeNode(6)
root.right.right = TreeNode(7)

# 找到节点 5 的第 2 个祖先
node = findNode(root, 5)
count = [0]
findAncestor(root, node, 2, count)

以上是本题的解决方案。