📌  相关文章
📜  检查两个节点是否在树中的同一路径上(1)

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

检查两个节点是否在树中的同一路径上

在树中,如果两个节点在同一路径上,那么它们之间的路径就是唯一的。如果检查两个节点是否在树中的同一路径上,我们可以先找到它们的最近公共祖先节点,然后分别从该节点向下遍历树来确定它们是否在同一路径上。

实现该算法可以使用树的遍历,具体步骤如下:

  1. 从根节点开始遍历树,如果遍历到的节点等于其中的一个节点,则将其添加到一个路径列表中。

  2. 当遍历到叶子节点时,返回到它的父节点。

  3. 如果找到另一个节点,也将其添加到路径列表中。

  4. 重复以上步骤,直到找到两个节点有共同的父节点。

  5. 从共同的父节点开始,按顺序遍历路径列表,如果路径相同则它们在同一路径上。

下面是一个Python实现该算法的示例代码:

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

class Solution:
    def findPath(self, root: TreeNode, node1: TreeNode, node2: TreeNode) -> bool:
        # 定义存储路径的栈
        stack1, stack2 = [], []

        # 查找节点1所在路径
        node = self.searchNode(root, node1, stack1)
        if not node:
            return False

        # 查找节点2所在路径
        node = self.searchNode(root, node2, stack2)
        if not node:
            return False

        # 找到两个节点的最近公共祖先节点
        ancestor = None
        while stack1 and stack2:
            x, y = stack1.pop(), stack2.pop()
            if x == y:
                ancestor = x
            else:
                break

        # 如果找到了共同的祖先节点,则判断路径是否相同
        if ancestor:
            path1 = self.getPath(ancestor, node1)
            path2 = self.getPath(ancestor, node2)
            return path1 == path2

        return False

    # 在以root为根节点的树中查找node节点,并将路径存储在stack中
    def searchNode(self, root: TreeNode, node: TreeNode, stack: List[TreeNode]) -> TreeNode:
        if not root:
            return None

        stack.append(root)

        if root == node:
            return root

        if self.searchNode(root.left, node, stack):
            return root.left

        if self.searchNode(root.right, node, stack):
            return root.right

        stack.pop()
        return None

    # 从根节点开始按顺序遍历到目标节点的路径
    def getPath(self, root: TreeNode, target: TreeNode) -> List[int]:
        path = []
        stack = [root]

        while stack:
            node = stack.pop()
            path.append(node.val)

            if node == target:
                return path[::-1]

            if node.left:
                stack.append(node.left)

            if node.right:
                stack.append(node.right)

        return path

在上述代码中,我们定义了两个栈stack1和stack2,分别用于存储节点1和节点2所在的路径。通过递归从根节点开始查找每个节点,并在查找过程中将经过的节点压入相应的栈中。然后,我们找到两个栈的最近公共祖先节点,并通过此节点检查两个路径是否相同。如果两个路径相同,则节点1和节点2在同一路径上。

以上是一个实现该算法的Python程序,Code片段如下:

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

class Solution:
    def findPath(self, root: TreeNode, node1: TreeNode, node2: TreeNode) -> bool:
        # 定义存储路径的栈
        stack1, stack2 = [], []

        # 查找节点1所在路径
        node = self.searchNode(root, node1, stack1)
        if not node:
            return False

        # 查找节点2所在路径
        node = self.searchNode(root, node2, stack2)
        if not node:
            return False

        # 找到两个节点的最近公共祖先节点
        ancestor = None
        while stack1 and stack2:
            x, y = stack1.pop(), stack2.pop()
            if x == y:
                ancestor = x
            else:
                break

        # 如果找到了共同的祖先节点,则判断路径是否相同
        if ancestor:
            path1 = self.getPath(ancestor, node1)
            path2 = self.getPath(ancestor, node2)
            return path1 == path2

        return False

    # 在以root为根节点的树中查找node节点,并将路径存储在stack中
    def searchNode(self, root: TreeNode, node: TreeNode, stack: List[TreeNode]) -> TreeNode:
        if not root:
            return None

        stack.append(root)

        if root == node:
            return root

        if self.searchNode(root.left, node, stack):
            return root.left

        if self.searchNode(root.right, node, stack):
            return root.right

        stack.pop()
        return None

    # 从根节点开始按顺序遍历到目标节点的路径
    def getPath(self, root: TreeNode, target: TreeNode) -> List[int]:
        path = []
        stack = [root]

        while stack:
            node = stack.pop()
            path.append(node.val)

            if node == target:
                return path[::-1]

            if node.left:
                stack.append(node.left)

            if node.right:
                stack.append(node.right)

        return path