题目
- 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
![]()
法一、indexOf+slice
- 根据前序遍历定位出根节点,根据中序遍历划分出左右子树,然后递归构建左右子树
var buildTree = function(preorder, inorder) {
if (preorder.length == 0) return null
const root = new TreeNode(preorder[0])
const mid = inorder.indexOf(preorder[0])//indexOf遍历找到根节点在中序遍历的下标
//递归左右子树
root.left = buildTree(preorder.slice(1,mid+1),inorder.slice(0,mid))//slice返回一个新的子数组
root.right = buildTree(preorder.slice(mid+1),inorder.slice(mid))//slice传递一个参数表示start一直到原数组末尾
return root
};
法二、哈希表+指针
var buildTree = function(preorder, inorder) {
// 使用一个哈希表存储中序遍历值及其索引
const inorderIndexMap = new Map();
inorder.forEach((value, index) => {
inorderIndexMap.set(value, index);
});
// 定义递归函数,传入前序遍历的开始索引和中序遍历的范围
const build = (preStart, preEnd, inStart, inEnd) => {
// 如果没有节点要处理,返回 null
if (preStart > preEnd) return null;
// 当前根节点是前序遍历的第一个元素
const rootVal = preorder[preStart];
const root = new TreeNode(rootVal);
// 找到根节点在中序遍历中的位置
const inRootIndex = inorderIndexMap.get(rootVal);
const leftTreeSize = inRootIndex - inStart; // 左子树的大小
// 递归构建左子树和右子树
root.left = build(preStart + 1, preStart + leftTreeSize, inStart, inRootIndex - 1);
root.right = build(preStart + leftTreeSize + 1, preEnd, inRootIndex + 1, inEnd);
return root;
};
// 调用递归函数
return build(0, preorder.length - 1, 0, inorder.length - 1);
};