[ 题目描述 ]:
[ 思路 ]:
- 递归构建,前序遍历是 [ 根节点,左孩子节点,右孩子节点 ],中序遍历是 [ 左孩子节点,根节点,右孩子节点]
- 根据这一特性,可以知道,前序遍历中前面的节点是后面节点的,父亲或祖宗
- 中序遍历中某个节点左边是他的左孩子们,右边是他的右孩子们
- 由此我们对前序遍历的第一个节点开始构建,他一定是父节点,再将他在中序遍历中左边的节点和右边的节点划分出来,用于构建他的左右孩子
- 以构建左孩子为例,求出左边孩子的个数n,由于前序遍历是 根左右 ,也就是说这些孩子一定在前序遍历的前 n+1个节点(第一个节点是父节点),将这 n 个前序遍历的节点和中序遍历的节点顺序列表进行新一轮递归
- 运行如下
# python代码
class Solution(object):
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: Optional[TreeNode]
"""
if not preorder or not inorder:
return None
root=TreeNode(preorder[0])
val_index=inorder.index(preorder[0])
left_inorder=inorder[0:val_index]
right_inorder=inorder[val_index+1:]
left_preoder=preorder[1:1+len(left_inorder)]
right_preoder=preorder[1+len(left_inorder):]
root.left=self.buildTree(left_preoder,left_inorder)
root.right=self.buildTree(right_preoder,right_inorder)
return root
[ 官方题解 ]:
- 方法一:递归,基本同上
- 方法二:迭代,依次枚举前序遍历中除了第一个节点以外的每个节点。如果 index 恰好指向栈顶节点,那么不断地弹出栈顶节点并向右移动 index,并将当前节点作为最后一个弹出的节点的右儿子;如果 index 和栈顶节点不同,则将当前节点作为栈顶节点的左儿子;
- 无论是哪一种情况,最后都将当前的节点入栈。
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
if not preorder:
return None
root = TreeNode(preorder[0])
stack = [root]
inorderIndex = 0
for i in range(1, len(preorder)):
preorderVal = preorder[i]
node = stack[-1]
if node.val != inorder[inorderIndex]:
node.left = TreeNode(preorderVal)
stack.append(node.left)
else:
while stack and stack[-1].val == inorder[inorderIndex]:
node = stack.pop()
inorderIndex += 1
node.right = TreeNode(preorderVal)
stack.append(node.right)
return root