LeetCode 105 前序中序遍历构造二叉树
1. 题目描述
给定一棵树的前序遍历
preorder
与中序遍历inorder
。请构造二叉树并返回其根节点。
2. 分析
之前已经分析过了前序遍历和中序遍历,我们可以知道
- 前序遍历的第一个节点一定是根节点
- 中序遍历的根节点两边分别是左右子树的中序遍历结果
所以,我们可以按照以下步骤得到结果:
- 先通过先序遍历找到当前树的根节点
- 通过找到的根节点在中序遍历中查找,将其分为左右两个子树的中序遍历
- 接着递归处理左右子树即可
3. 代码
private int index;//记录当前访问到先序遍历中的第几个元素了
public TreeNode buildTree(int[] preorder, int[] inorder)
{
index = 0;
return buildTreeHelper(preorder, inorder, 0, inorder.length);
}
/**
* @param preorder 当前拆分的前序遍历数组
* @param inorder 当前拆分的中序遍历数组
* @param left 中序遍历数组起始位置
* @param right 中序遍历数组结束位置
* @return
*/
private TreeNode buildTreeHelper(int[] preorder, int[] inorder, int left, int right)
{
//说明中序遍历结果为空,当前范围内的树为空树
if (left >= right)
{
return null;
}
//遍历结束
if (index >= preorder.length)
{
return null;
}
//根据当前根节点值创建出节点
TreeNode root = new TreeNode(preorder[index]);
//当前节点处理完毕,开始处理下一个节点
index++;
//根据该节点在中序遍历中的位置,将中序遍历划分成两个
int pos = find(inorder, left, right, root.val);
//[left,pos)表示root左子树的遍历结果
root.left = buildTreeHelper(preorder, inorder, left, pos);
//[pos+1,right)表示root右子树的遍历结果
root.right = buildTreeHelper(preorder, inorder, pos + 1, right);
return root;
}
/**
* 找到分开中序遍历数组节点的下标
* @param inorder 中序遍历数组
* @param left 中序遍历数字起始位置
* @param right 中序遍历数字结束位置
* @param find 要查找的节点值
* @return
*/
private int find(int[] inorder, int left, int right, int find)
{
for (int i = left; i < right; i++)
{
if (inorder[i] == find)
{
return i;
}
}
return -1;
}