题目链接
思路:
前序遍历为 根左右,中序遍历为 左根右,那么前序遍历序列中的第一个节点即为整棵树的根节点,在中序遍历序列中找到根节点,在中序遍历中根节点的左侧全部都是根节点的左孩子,右侧全部都是根节点的右孩子
利用上面的性质,我们可以进行递归查找根节点,然后进行拼接即可
例如:
前序:1 2 3 4 5 6
中序:3 2 4 1 5 6
前序中根节点为 1,中序中 3 2 4为 1 的左孩子,中序中 5 6 为 1 的右孩子
前序中左孩子前序序列为 2 3 4,中序为 3 2 4,2为根节点,3为左孩子,4为右孩子
前序中右孩子前序序列为 5 6,中序为 5 6,5为根节点,6为右孩子
最终得到完整的二叉树
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || inorder == null) {
return null;
}
return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
}
/**
*
* @param preorder
* @param preStart 前序的开始位置
* @param preEnd 前序的结束位置
* @param inorder
* @param inStart 中序的开始位置
* @param inEnd 中序的结束位置
* @return
*/
private TreeNode buildTree(int[] preorder, int preStart, int preEnd,
int[] inorder, int inStart, int inEnd) {
if (preStart > preEnd || inStart > inEnd) {
return null;
}
// 根节点
int rootVal = preorder[preStart];
// 找到中序中根节点的位置
int rootInOrderPos = inStart;
for (int i = inStart; i <= inEnd; i++) {
if (inorder[i] == rootVal) {
rootInOrderPos = i;
break;
}
}
TreeNode root = new TreeNode(rootVal);
// 递归寻找根节点的左孩子
root.left = buildTree(preorder, preStart + 1,
preStart + rootInOrderPos - inStart,
inorder, inStart,
rootInOrderPos - 1);
// 递归寻找根节点的右孩子
root.right = buildTree(preorder, preStart + rootInOrderPos - inStart + 1,
preEnd,
inorder, rootInOrderPos + 1,
inEnd);
return root;
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}