面试题07. 重建二叉树

image.png
问题就是查找前序遍历和中序遍历中根节点,左节点,右节点 三者之前的界限,这个自己动手比划一下 ,例如就三个数 前序【3,9,20】 中序【9,3,20】,不然递归非让脑子浆糊了。
1前序遍历是 1根节点 2 左节点 3 右节点
2中序遍历是 1左节点 2根节点 3右节点
3根据前序遍历可以确定根节点是前序数组的第一个数preorder[0]
4 查找中序遍历左右节点的边界,中序遍历根节点的位置inorder[1] ,可以发现 inorder[1]左边都是树左节点的,左节点个数是1个,即[9],inorder[1]右边都是树右节点的,右节点的个数3,即[15,20,7],
5 查找前序遍历左右节点的边界,前序遍历第一个节点是根节点,依次是左节点和右节点,而我们中序遍历已经知道左节点的个数和右节点个数,所以preorder[1:1+1]即[9] ,而preorder[1+1:]就是右节点。
6 总结 边界索引里的中序遍历的根节点位置,即是表示出了根节点索引也是左节点的个数。

  1. package main
  2. import "fmt"
  3. type TreeNode struct {
  4. Val int
  5. Left *TreeNode
  6. Right *TreeNode
  7. }
  8. func buildTree(preorder []int, inorder []int) *TreeNode {
  9. if len(preorder) == 0 {
  10. return nil
  11. }
  12. rootIdx := 0
  13. for i := range inorder {
  14. if inorder[i] == preorder[0] {
  15. rootIdx = i
  16. break
  17. }
  18. }
  19. root := &TreeNode{Val: preorder[0]}
  20. root.Left = buildTree(preorder[1:rootIdx+1], inorder[:rootIdx])
  21. root.Right = buildTree(preorder[rootIdx+1:], inorder[rootIdx+1:])
  22. return root
  23. }
  24. func printTree(root *TreeNode) {
  25. if root == nil {
  26. return
  27. }
  28. fmt.Println(root.Val)
  29. printTree(root.Left)
  30. printTree(root.Right)
  31. }
  32. func main() {
  33. r := buildTree([]int{3, 9, 20, 15, 7}, []int{9, 3, 15, 20, 7})
  34. printTree(r)
  35. }