参考题解:二叉树的前序遍历 (分支思想)
这道题的思路包括:
- 根据前序遍历和中序遍历,可以很轻易看出,前序遍历可以获取根节点,然后将中序遍历划分为两个子区间,这是一个清晰的分治问题。
- 但是,如何根据前序遍历数组,将两个遍历数组联系起来,这就需要通过 HashMap 存储每个前序遍历节点的位置。
- 随后,建树函数需要存储前序遍历和中序遍历分别对应的数组中的起始和终止的位置。
- 最后,分治时的子树的左右节点,对应的前序、中序遍历的起始、终止位置,这里需要记忆一下。可以分别记忆前序和中序的内容,因为都是两两对应的。
public class Solution {
private Map<Integer, Integer> reverses;
private int[] preorder;
public TreeNode buildTree(int[] preorder, int[] inorder) {
int preLen = preorder.length;
int inLen = inorder.length;
if (preLen != inLen) {
return null;
}
this.preorder = preorder;
reverses = new HashMap<>(inLen);
for (int i = 0; i < inLen; i++) {
reverses.put(inorder[i], i);
}
return buildTree(0, preLen - 1, 0, inLen - 1);
}
private TreeNode buildTree(int preL, int preR, int inL, int inR) {
if (preL > preR || inL > inR) {
return null;
}
int pivot = preorder[preL];
TreeNode root = new TreeNode(pivot);
int pivotIndex = reverses.get(pivot);
root.left = buildTree(preL + 1, preL + (pivotIndex - inL), inL, pivotIndex - 1);
root.right = buildTree(preL + (pivotIndex - inL) + 1, preR, pivotIndex + 1, inR);
return root;
}
}