diff --git a/problems/0106.从中序与后序遍历序列构造二叉树.md b/problems/0106.从中序与后序遍历序列构造二叉树.md index 3518343f..bde61a75 100644 --- a/problems/0106.从中序与后序遍历序列构造二叉树.md +++ b/problems/0106.从中序与后序遍历序列构造二叉树.md @@ -794,6 +794,60 @@ func rebuild(inorder []int, postorder []int, rootIdx int, l, r int) *TreeNode { } ``` +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func buildTree(inorder []int, postorder []int) *TreeNode { + if len(postorder) == 0 { + return nil + } + + // 后序遍历数组最后一个元素,就是当前的中间节点 + rootValue := postorder[len(postorder)-1] + root := &TreeNode{Val:rootValue} + + // 叶子结点 + if len(postorder) == 1 { + return root + } + + // 找到中序遍历的切割点 + var delimiterIndex int + for delimiterIndex = 0; delimiterIndex < len(inorder); delimiterIndex++ { + if inorder[delimiterIndex] == rootValue { + break; + } + } + + // 切割中序数组 + // 左闭右开区间:[0, delimiterIndex) + leftInorder := inorder[:delimiterIndex] + // [delimiterIndex + 1, end) + rightInorder := inorder[delimiterIndex+1:] + + // postorder 舍弃末尾元素 + postorder = postorder[:len(postorder)-1] + + // 切割后序数组 + // 依然左闭右开,注意这里使用了左中序数组大小作为切割点 + // [0, len(leftInorder)) + leftPostorder := postorder[:len(leftInorder)] + // [len(leftInorder), end) + rightPostorder := postorder[len(leftInorder):] + + root.Left = buildTree(leftInorder, leftPostorder) + root.Right = buildTree(rightInorder, rightPostorder) + + return root +} +``` + 105 从前序与中序遍历序列构造二叉树 ```go @@ -829,6 +883,60 @@ func build(pre []int, in []int, root int, l, r int) *TreeNode { } ``` +```go +/** + * 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 + } + + // 前序遍历数组第一个元素,就是当前的中间节点 + rootValue := preorder[0] + root := &TreeNode{Val:rootValue} + + // 叶子结点 + if len(preorder) == 1 { + return root + } + + // 找到中序遍历的切割点 + var delimiterIndex int + for delimiterIndex = 0; delimiterIndex < len(inorder); delimiterIndex++ { + if inorder[delimiterIndex] == rootValue { + break + } + } + + // 切割中序数组 + // 左闭右开区间:[0, delimiterIndex) + leftInorder := inorder[:delimiterIndex] + // [delimiterIndex + 1, end) + rightInorder := inorder[delimiterIndex+1:] + + // preorder 舍弃首位元素 + preorder = preorder[1:] + + // 切割前序数组 + // 依然左闭右开,注意这里使用了左中序数组大小作为切割点 + // [0, len(leftInorder)) + leftPreorder := preorder[:len(leftInorder)] + // [len(leftInorder), end) + rightPreorder := preorder[len(leftInorder):] + + root.Left = buildTree(leftPreorder, leftInorder) + root.Right = buildTree(rightPreorder, rightInorder) + + return root +} +``` + ### JavaScript