根据一棵树的前序遍历与中序遍历构造二叉树

转载自:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/4chong-jie-fa-di-gui-zhan-dui-lie-by-sdwwld/

 

方法一:使用栈解决

如果使用栈来解决首先要搞懂一个知识点,就是前序遍历挨着的两个值比如m和n,他们会有下面两种情况之一的关系。

1,n是m左子树节点的值。

2,n是m右子树节点的值或者是m某个祖先节点的右节点的值。

对于第一个知识点我们很容易理解,如果m的左子树不为空,那么n就是m左子树节点的值。

对于第二个问题,如果一个结点没有左子树只有右子树,那么n就是m右子树节点的值,如果一个结点既没有左子树也没有右子树,那么n就是m某个祖先节点的右节点,我们只要找到这个祖先节点就好办了。

搞懂了这点,代码就很容易写了,下面看下完整代码

public TreeNode buildTree(int[] preorder, int[] inorder) {
    if (preorder.length == 0)
        return null;
    Stack<TreeNode> s = new Stack<>();
    //前序的第一个其实就是根节点
    TreeNode root = new TreeNode(preorder[0]);
    TreeNode cur = root;
    for (int i = 1, j = 0; i < preorder.length; i++) {
        //第一种情况
        if (cur.val != inorder[j]) {
            cur.left = new TreeNode(preorder[i]);
            s.push(cur);
            cur = cur.left;
        } else {
            //第二种情况
            j++;
            //找到合适的cur,然后确定他的右节点
            while (!s.empty() && s.peek().val == inorder[j]) {
                cur = s.pop();
                j++;
            }
            //给cur添加右节点
            cur = cur.right = new TreeNode(preorder[i]);
        }
    }
    return root;
}

 

方法二:递归法

class Solution {
    private int in = 0;
    private int pre = 0;
    private int[] preorder;
    private int[] inorder;

public TreeNode buildTree(int[] preorder, int[] inorder) {
    this.preorder = preorder;
    this.inorder = inorder;
    return build(Integer.MIN_VALUE);
}

private TreeNode build(int stop) {
    if (pre >= preorder.length)
        return null;
    if (inorder[in] == stop) {
        in++;
        return null;
    }

    TreeNode node = new TreeNode(preorder[pre++]);
    node.left = build(node.val);    //左子树  当中序遍历下一节点与前序遍历相同时,到达叶节点
    node.right = build(stop);       //右子树  当中序遍历下一节点为当前节点的根节点时,到达叶节点
    return node;
}

 

posted @ 2021-01-07 14:10  zeroPatrick  阅读(183)  评论(0编辑  收藏  举报