算法:
该类题目的核心在于利用前序或者后序遍历找到根节点,利用中序遍历分成左右两棵子树,然后递归操作即可。
前序遍历:根节点,左子树,右子树
中序遍历:左子树,根节点,右子树
后序遍历:左子树,右子树,根节点
前序/后序先找到根节点,利用两种遍历场景的左/右子树的长度相同,找到中序的左右子树
题目1: 前序和中序狗仔二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
代码实现:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func buildTree(preorder []int, inorder []int) *TreeNode {
if len(preorder) == 0 {
return nil
}
root := new(TreeNode)
root.Val = preorder[0]
var i int
for i<len(inorder) {
if preorder[0] == inorder[i] { // 记录中序遍历中的父亲节点位置
break
}
i++
}
l := len(inorder[:i]) // 同一个棵树的长度相同
root.Left = buildTree(preorder[1:l+1],inorder[:i])
root.Right = buildTree(preorder[l+1:],inorder[i+1:])
return root
}
// 算法:
// 前序遍历:根节点,左子树,右子树
// 中序遍历:左子树,根节点,右子树
// 中序先找到根节点,利用两种遍历场景的左/右子树的长度相同,找到中序的左右子树
执行结果:
题目2:中序和后续构造二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
代码实现:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func buildTree(inorder []int, postorder []int) *TreeNode {
if len(inorder) == 0 {
return nil
}
l := len(postorder)
root := &TreeNode{Val:postorder[l-1]}
i:=0
for i<len(inorder) {
if inorder[i] == root.Val {
break
}
i++
}
root.Left = buildTree(inorder[:i],postorder[:len(inorder[:i])])
root.Right = buildTree(inorder[i+1:],postorder[len(inorder[:i]):l-1])
return root
}
执行结果: