题目来源
分析
原则:
- 前序遍历是从最顶层根节点开始,中序遍历是从最底层左节点开始的。
- 前序遍历得到根节点,中序遍历由前序遍历得到的根节点分为左右子树。
- 假如从树的根节点开始,遍历前序序列直到与中序序列中的第一个元素相等时,遍历得到的节点都为该根节点的最左侧所有节点。
- 之后从最底层开始遍历子树的根节点得到其右子树。
总结:
- 前序遍历: 中、左1、左2、…、左n-1、左n、右n。
- 中序遍历: 左n、左n-1、右n、…、左1、中、右。
- 根据前序序列与中序序列的遍历关系,可以很容易得到根节点的最左侧所有节点,接着再反向遍历得到的最左侧节点(使用栈),得到左节点为根节点的子树的右节点。
- 关键点:中、左n。
- 先使用前序遍历得到根节点的最左侧子节点,再根据中序序列从前序遍历中得到子树右节点。
- 前序遍历得到节点集,中序遍历改变关注的子树对象。
代码:
使用递归(略)。
使用迭代:
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder == null || preorder.length == 0){
return null;
}
// 用来存放遍历的前序序列节点的栈,深度优先原理,即后进先出
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode root = new TreeNode(preorder[0]);
stack.push(root);
int indexInorder = 0;
TreeNode node;
// 遍历前序序列
for(int i=1; i<preorder.length; i++){
node = stack.peek(); // 遍历栈顶元素
// 判断遍历到的前序序列元素是否与当前中序序列的元素相等
if(node.val != inorder[indexInorder]){ // 不相等
node.left = new TreeNode(preorder[i]);
stack.push(node.left);
}else{
// 相等,说明是子树根节点
while(!stack.isEmpty() && stack.peek().val == inorder[indexInorder]){
node = stack.pop();
indexInorder++;
}
// 构造树的右子树
node.right = new TreeNode(preorder[i]);
stack.push(node.right);
}
}
return root;
}
}
本文解析了如何利用前序遍历和中序遍历构建二叉树,通过理解节点关系,找到根节点的左边界并构造右子树。关键在于找到前序序列中的'中'元素,以此划分左右子树。
569

被折叠的 条评论
为什么被折叠?



