算法小白,2024年2月21日,开始挑战在掘金发布“每日”系列。 (节假日可能会出门所以不算) 涉及到算法,type challenge 等,感兴趣的小伙伴可以持续关注督促互勉 🚀🚀🚀
算法
题意理解
根据二叉树的中序遍历和后序遍历结果,构造出二叉树
思路
- 二叉树的后序遍历最后一个元素就是二叉树的根节点
- 二叉树的中序遍历,根节点之前为左子树的中序号遍历结果,根节点之后为右子树的中序遍历结果
- 同理可得对于后续遍历,根节点索引之前就是左子树的后序遍历,之后为右子树的后续遍历
- 使用递归,即可找到所有子树的根节点
解题
const buildTree = (inorder, postorder) => {
if (!inorder.length) return
const rootVal = postorder.at(-1)
const mid = inorder.indexOf(rootVal)
const root = new ListNode(rootVal)
root.left = buildTree(inorder.slice(0, mid), postorder.slice(0, mid))
root.right = buildTree(inorder.slice(mid + 1), postorder.slice(mid, postorder.length - 1))
return root
}
优化
👆解法存在的问题是,每次递归都会调用 indexOf 和 slice 方法,会造成额外的时间消耗。
可以使用哈希表保存索引和值的对应关系,用位置计算代替 slice
const buildTree = (inorder, postorder) => {
const indexMap = new Map()
inorder.forEach((val, index) => indexMap.set(val, index))
// 用来计算末尾位置的变化
let length = postorder.length
const helper = (start, end) => {
const rootVal = postorder[length--]
const root = new TreeNode(rootVal)
const index = indexMap.get(rootVal)
root.left = helper(start, index - 1)
root.rigth = helper(index + 1, end)
return root
}
helper(0, inorder.length - 1)
}