「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」。
题目
链接:leetcode-cn.com/problems/co…
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
示例 1:
**输入:**inorder = [9,3,15,20,7], postorder = [9,15,7,20,3] 输出:[3,9,20,null,null,15,7]
示例 2:
**输入:**inorder = [-1], postorder = [-1] 输出:[-1]
提示:
1 <= inorder.length <= 3000postorder.length == inorder.length-3000 <= inorder[i], postorder[i] <= 3000inorder和postorder都由 不同 的值组成postorder中每一个值都在inorder中inorder保证是树的中序遍历postorder保证是树的后序遍历
思路1, 递归
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {number[]} inorder
* @param {number[]} postorder
* @return {TreeNode}
*/
var buildTree = function(inorder, postorder) {
if(!inorder.length) return null
let n = postorder.length
let tmp = postorder[n-1],mid = inorder.indexOf(tmp)
let root = new TreeNode(tmp)
root.left = buildTree(inorder.slice(0,mid),postorder.slice(0,mid))
root.right = buildTree(inorder.slice(mid + 1),postorder.slice(mid,n-1))
return root
};
思路2,递归简便版
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {number[]} inorder
* @param {number[]} postorder
* @return {TreeNode}
*/
var buildTree = function(inorder, postorder) {
let build = (inorder) => {
if(!inorder.length) return null
let tmp = postorder.pop(),mid = inorder.indexOf(tmp)
let root = new TreeNode(tmp)
root.right = build(inorder.slice(mid + 1))
root.left = build(inorder.slice(0,mid))
return root
}
return build(inorder)
};
思路3,参考解法
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {number[]} inorder
* @param {number[]} postorder
* @return {TreeNode}
*/
var buildTree = function(inorder, postorder) {
let p = i = postorder.length - 1;
let build = (stop) => {
if(inorder[i] != stop) {
let root = new TreeNode(postorder[p--])
root.right = build(root.val)
i--
root.left = build(stop)
return root
}
return null
}
return build()
};
思路4
找出根节点
后序遍历的最后一个节点就是根节点
在中序遍历中是:左根右的方式遍历的,因此根节点左侧是左树,右侧是右树
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {number[]} inorder
* @param {number[]} postorder
* @return {TreeNode}
*/
var buildTree = function (inorder, postorder) {
// 判断临界情况,如果两个参数都为空则节点为 null
if (!inorder.length || !postorder.length) return null
// 创建一个根节点开始遍历,后序遍历的最后一个元素是根节点
let node = new TreeNode(postorder[postorder.length - 1])
// 在中序遍历中找到这个节点所在的位置,左侧左树,右侧右树
let index = inorder.indexOf(postorder.pop())
// 划分 inorder,postorder 数组
// 左树传入中序遍历 index 左侧的节点,也就是左树的中序遍历结果
// 同时后序遍历的结果也需要发生改变,因为根节点位置左侧就是左树
// 所以对应的后序遍历数组中,同样通过 index 来拆分
node.left = buildTree(inorder.slice(0, index), postorder.slice(0, index))
node.right = buildTree(inorder.slice(index + 1), postorder.slice(index))
return node
};