[leetCode]07.重建二叉树

在这里插入图片描述

递归

前序遍历为:| 根结点 | 左子树 | 右子树 |
中序遍历为:| 左子树 | 根结点 | 右子树 |

以前序遍历中的根节点到中序遍历中寻找根节点,这样就能知道左右子树的长度。左右子树有符合相同的查找模式,所以可以使用递归。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length == 0 || inorder.length == 0)
                return null;
        int startPreorder = 0, endPreorder = preorder.length - 1;
        int startInorder = 0, endInorder = inorder.length - 1;
        return reconstructTree(
            preorder,
            startPreorder,
            endPreorder,
            inorder,
            startInorder,
            endInorder);
    }

    private TreeNode reconstructTree(
        int[] preorder,
        int startPreorder, 
        int endPreorder,
        int[] inorder,
        int startInorder,
        int endInorder){
            int rootVal = preorder[startPreorder];
            TreeNode root = new TreeNode(rootVal);
            if(startPreorder == endPreorder){
                return root;
            }
            int rootInorder = 0;    
            while(rootInorder <= endInorder && inorder[rootInorder] != rootVal){
                ++rootInorder;
            }
            if(inorder[rootInorder] != rootVal){
                throw new RuntimeException("input error");
            }
            int leftNodeNums = rootInorder - startInorder;
            int leftPreoderEnd = startPreorder + leftNodeNums;
            if(leftNodeNums > 0){
                root.left = reconstructTree(
                        preorder,
                        startPreorder+1,
                        leftPreoderEnd,
                        inorder,
                        startInorder,
                        rootInorder-1);
            }
            if(leftNodeNums < endPreorder - startPreorder){
                 root.right = reconstructTree(
                        preorder,
                        leftPreoderEnd+1,
                        endPreorder,
                        inorder,
                        rootInorder+1,
                        endInorder);
            }
            return root;
        }
} 

上面的代码使用了指针。可以通过哈希表记录中序遍历中根结点的索引,这样就能快速找到前序遍历中的根结点在中序遍历的位置

class Solution {
    HashMap<Integer,Integer> map;//记录中序遍历中的结点下标
    int[] preorder_copy;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length == 0 || inorder.length == 0)
                return null;
        //初始化map用于快速查询根节点下标
        map = new HashMap<>();
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i],i);
        }
        preorder_copy = preorder;
        return rebuild(0 ,0, inorder.length - 1);
    }

    private TreeNode rebuild(int preRoot, int inLeft, int inRight){
        if(inLeft > inRight) return null;
        TreeNode root = new TreeNode(preorder_copy[preRoot]);
        int i = map.get(preorder_copy[preRoot]);
        root.left = rebuild(preRoot+1,inLeft,i-1);
        root.right = rebuild(preRoot + i - inLeft + 1,i+1,inRight);
        return root;
    }
}

迭代

leetCode官方题解

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length == 0 || inorder.length == 0)
                return null;
        TreeNode root  = new TreeNode(preorder[0]);
        LinkedList<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        int index = 0;
        for(int i = 1; i < preorder.length; i++){
            int nextRootVal = preorder[i];//下一个结点的值
            TreeNode node = stack.peek();//上一个结点
            if(node.val != inorder[index]){
                node.left = new TreeNode(nextRootVal);
                stack.push(node.left);
            }else {
                while(!stack.isEmpty() && stack.peek().val == inorder[index]){
                   ++index;
                   node = stack.pop();
                }
                node.right = new TreeNode(nextRootVal);
                stack.push(node.right);
            }
        }
        return root;
    }

}
posted @ 2020-08-02 11:41  消灭猕猴桃  阅读(61)  评论(0编辑  收藏  举报