1. 题目概述
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
限制:0 <= 节点个数 <= 5000
2. 题目分析
首先,这道题目考察的是二叉树的基本知识。前序遍历即就是先打印根,再打印左右节点。中序遍历是先打印左节点,再打印根节点,最后打印右节点。给出了前序遍历和中序遍历,需要构建出二叉树。首先,我的大方向思路是这样的:
1. 在前序遍历中找到第一个数据,就是根节点。
2. 在中序遍历中找到这个节点,分别推出它的左孩子和右孩子。
3. 以此类推,直到结束。
总体是以前序遍历的思想进行切入,我画了一张图描述了其过程:
3. 解题代码
class Solution {
int preIndex= 0;
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder == null || inorder == null || preorder.length == 0 || inorder.length == 0) {
return null;
}
return buildTreeChild(preorder, inorder, 0, inorder.length-1);
}
public TreeNode buildTreeChild( int[] preorder,int[] inorder,int inbegin, int inend) {
//终止条件 判断是否有左树或者右树
if (inbegin > inend) {
return null;
}
//在前序遍历中new 根节点
TreeNode root = new TreeNode(preorder[preIndex]);
//在中序遍历找到pi所在下标元素
int rootIndex = findIndexOfInorder(inorder, inbegin, inend, preorder[preIndex]);
preIndex++;
root.left = buildTreeChild(preorder, inorder, inbegin, rootIndex-1);
root.right = buildTreeChild(preorder, inorder, rootIndex+1, inend);
return root;
}
private int findIndexOfInorder(int[] inorder, int inbegin, int inend, int val) {
for (int i = inbegin; i <= inend; i++) {
if (inorder[i] == val) {
return i;
}
}
return -1;
}
}
4. 思考总结
由于二叉树的结构所致,二叉树的大部分题目都是要用递归来写的。而切入点就是二叉树的四种遍历,前序遍历,中序遍历,后序遍历和层序遍历,因此熟练掌握四种遍历方式是非常必要的。
其实,也可以根据后序遍历和中序遍历构建二叉树道理相同,和前序遍历一样,只是传入参数和遍历顺序不同。就不详细写了呦,附上代码一只:
public int postIndex = 0;
public TreeNode buildTreeChild(int[] inorder, int[] postorder,int inbegin, int inend) {
//终止条件 判断是否有左树或者右树
if (inbegin > inend) {
return null;
}
//new 根节点
TreeNode root = new TreeNode(postorder[postIndex]);
//在中序遍历找到pi所在下标元素
int rootIndex = findIndexOfInorder(inorder, inbegin, inend, postorder[postIndex]);
postIndex--;
root.right = buildTreeChild(inorder,postorder, rootIndex+1,inend);
root.left = buildTreeChild(inorder, postorder, inbegin,rootIndex-1);
return root;
}
private int findIndexOfInorder(int[] inorder, int inbegin, int inend, int val) {
for (int i = inbegin; i <= inend; i++) {
if (inorder[i] == val) {
return i;
}
}
return -1;
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (postorder == null || inorder == null) {
return null;
}
if (postorder.length == 0 || inorder.length == 0) {
return null;
}
postIndex = postorder.length-1;
return buildTreeChild(inorder, postorder, 0, inorder.length-1);
}