剑指Offer面试题6 & Leetcode105

剑指Offer面试题6 & Leetcode105

Construct Binary Tree from Preorder and Inorder Traversal

重建二叉树

Given preorder and inorder traversal of a tree, construct the binary tree.

解题思路

  考虑:前序遍历的第一个元素即为根节点的值,然后在中序遍历中找到该元素,则位于其前的为左子树的中序遍历,位于其后的为右子树的中序遍历。同理,前序遍历中第一个元素后先是左子树的前序遍历,然后是右子树的前序遍历。根据这个特点,用递归的方法实现二叉树的重建。

  注意这道题,如果想减小运行时间,在递归过程中尽量传递原数组中各子树遍历的序号,而不是构建新的数组进行传递。下面两种解法,一种为传递数组,一种为传递序号,均AC但时间不同。

Solution1 时间较长

public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length == 0 && inorder.length == 0) 
            return null;
        TreeNode root = new TreeNode(preorder[0]);
        int flag = -1;
        for(int i=0;iif(inorder[i] == root.val){
                flag = i;
                break;
            }
        }
        int[] newInorderLeft = new int[flag];
        int[] newPreorderLeft = new int[flag];
        int[] newInorderRight = new int[inorder.length-flag-1];
        int[] newPreorderRight = new int[preorder.length-flag-1];
        for(int i=0;ifor(int i=0;i1];
        }
        for(int i=0;i1;i++){
            newInorderRight[i] = inorder[flag+1+i];
        }
        for(int i=0;i1;i++){
            newPreorderRight[i] = preorder[flag+1+i];
        }
        root.left = buildTree(newPreorderLeft,newInorderLeft);
        root.right = buildTree(newPreorderRight, newInorderRight);
        return root;
    }

Solution2 时间较短

public TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder.length == 0 && inorder.length == 0)
            return null;
        return helper(0, 0, inorder.length - 1, preorder, inorder);
    }

public TreeNode helper(int preStart, int inStart, 
    int inEnd, int[] preorder, int[] inorder) {
        if (preStart >= preorder.length || inStart > inEnd)
            return null;
        TreeNode root = new TreeNode(preorder[preStart]);
        int flag = -1;
        for (int i = inStart; i <= inEnd; i++) {
            if (inorder[i] == root.val) {
                flag = i;
                break;
            }
        }
        root.left = helper(preStart + 1, inStart, flag - 1, preorder, inorder);
        //注意对于右子树的前序遍历,开始的序号要减去其中序遍历开始的序号,防止溢出, 即 flag + 1 - inStart 为右子树针对此时的根节点的位移量。
        root.right = helper(preStart + flag + 1 - inStart, flag + 1, inEnd, preorder, inorder);
        return root;
    }

你可能感兴趣的:(剑指offer-java实现,leetcode-java)