105和106都是根据二叉树的遍历结果来重构二叉树,这两题的解题思路是一致的,因此将两题放在一起记录。
- 105
首先根据前序遍历的结果数组得到根节点(每个左、右子树的根节点)对应的大小,然后根据中序遍历结果数组可以求出左、右子树的数组下标,然后递归地从根节点开始构建左、右子树;
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || preorder.length == 0 || inorder == null || inorder.length == 0 || preorder.length != inorder.length) {
return null;
}
return help(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
}
private TreeNode help(int[] preorder, int pStart, int pEnd, int[] inorder, int iStart, int iEnd) {
//递归的第一步:递归终止条件,避免死循环
if (pStart > pEnd || iStart > iEnd) {
return null;
}
//重建根节点
TreeNode root = new TreeNode(preorder[pStart]);
int index = 0;
//index找到根节点在中序遍历的位置
while (inorder[index] != preorder[pStart]) {
index++;
}
//重建左子树
root.left = help(preorder, pStart + 1, pStart + index - iStart, inorder, iStart, index - 1);
//重建右子树
root.right = help(preorder, pStart + index + 1 - iStart, pEnd, inorder, index + 1, iEnd);
return root;
}
}
- 106
与105基本一致,可以从后序遍历的数组中得到根节点(左、右子树的根节点)对应的大小,然后同样通过中序遍历找到左、右子树包含元素所对应的的数组下标,然后递归创建左、右子树。
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
if (postorder == null || postorder.length == 0 || inorder == null || inorder.length == 0 || postorder.length != inorder.length) {
return null;
}
return help(postorder, 0, postorder.length - 1, inorder, 0, inorder.length - 1);
}
private TreeNode help(int[] postorder, int pStart, int pEnd, int[] inorder, int iStart, int iEnd) {
//递归的第一步:递归终止条件,避免死循环
if (pStart > pEnd || iStart > iEnd) {
return null;
}
//重建根节点
TreeNode root = new TreeNode(postorder[pEnd]);
int index = iStart;
//index找到根节点在中序遍历的位置
while (inorder[index] != postorder[pEnd]) {
index++;
}
//重建左子树
root.left = help(postorder, pStart, pStart + index -iStart -1, inorder, iStart, index - 1);
//重建右子树
root.right = help(postorder, pStart + index -iStart, pEnd-1, inorder, index + 1, iEnd);
return root;
}
}