📅  最后修改于: 2023-12-03 15:10:51.708000             🧑  作者: Mango
在树结构中,我们可能需要检查两个节点是否在根节点的同一子树中,即它们是否具有共同的祖先节点。
我们可以从根节点开始遍历整棵树,寻找每个节点的祖先,然后比较两个节点的祖先是否相同。如果相同,则它们在同一子树中,否则不在。
# 定义二叉树节点类
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
# 寻找一个节点的祖先列表
def find_ancestor(root, node, path):
if not root:
return False
path.append(root)
if root == node:
return True
if (root.left and find_ancestor(root.left, node, path)) or \
(root.right and find_ancestor(root.right, node, path)):
return True
path.pop()
return False
# 检查两个节点是否在同一子树中
def is_same_subtree(root, p, q):
path_p = []
path_q = []
find_ancestor(root, p, path_p)
find_ancestor(root, q, path_q)
if len(path_p) <= 1 or len(path_q) <= 1 or path_p[0] != path_q[0]:
return False
i = 1
while i < len(path_p) and i < len(path_q):
if path_p[i] != path_q[i]:
break
i += 1
return path_p[i-1]
时间复杂度为 O(n)
,其中 n
是树中节点的数量,空间复杂度为 O(n)
,因为我们需要存储每个节点的祖先。
我们可以分别查找两个节点到根节点的路径,然后比较它们的路径是否相同。如果相同,则它们在同一子树中,否则不在。
# 查找从根节点到目标节点的路径
def find_path(root, node, path):
if not root:
return False
path.append(root)
if root == node:
return True
if (root.left and find_path(root.left, node, path)) or \
(root.right and find_path(root.right, node, path)):
return True
path.pop()
return False
# 检查两个节点是否在同一子树中
def is_same_subtree(root, p, q):
path_p = []
path_q = []
find_path(root, p, path_p)
find_path(root, q, path_q)
if not path_p or not path_q:
return False
i = 0
while i < len(path_p) and i < len(path_q):
if path_p[i] != path_q[i]:
break
i += 1
return path_p[i-1]
时间复杂度为 O(n)
,空间复杂度为 O(n)
,因为我们需要存储每个节点到根节点的路径。