剑指 Offer 07. 重建二叉树

递归:

public TreeNode buildTree(int[] preorder, int[] inorder) {
        int len = preorder.length;
        if(len == 0) return null;
        TreeNode head = new TreeNode(preorder[0]);
        int index = 0;
        for(int i = 0;i<inorder.length;i++){
            if(inorder[i] == preorder[0]){
                index = i;
                break;
            }
        }
        head.left = buildTree(Arrays.copyOfRange(preorder,1,index+1),
                Arrays.copyOfRange(inorder,0,index));
        head.right = buildTree(Arrays.copyOfRange(preorder,index+1,len),
                Arrays.copyOfRange(inorder,index+1,len));
        return head;
    }

public TreeNode buildTree(int[] preorder, int[] inorder) {
        int len = preorder.length;
        if(len == 0) return null;
        TreeNode head = new TreeNode(preorder[0]);
        int index = 0;
        for(int i = 0;i<inorder.length;i++){
            if(inorder[i] == preorder[0]){
                index = i;
                break;
            }
        }
        int[] pre_left = Arrays.copyOfRange(preorder,1,index+1);
        int[] in_left = Arrays.copyOfRange(inorder,0,index);
        int[] pre_right = Arrays.copyOfRange(preorder,index+1,len);
        int[] in_right = Arrays.copyOfRange(inorder,index+1,len);
        head.left = buildTree(pre_left, in_left);
        head.right = buildTree(pre_right, in_right);
        return head;
    }

 只是拷贝了新数组,内存消耗就减了一半。

但是性能还是不行啊,除了递归还能怎么做?

指针直接完成:

public TreeNode buildTree(int[] preorder, int[] inorder) {
        int len = preorder.length;
        if (len == 0) return null;
        return dfs(len,preorder,0,inorder,0);
    }

    // 从前序和中序构造二叉树,前序和中序是大数组中的一段[start, start + count)
    private TreeNode dfs(int count, int[] preOrder, int preStart, int[] inOrder, int inStart) {
        if (count <= 0) return null;

        int rootValue = preOrder[preStart];
        TreeNode root = new TreeNode(rootValue);

        // 从inorder中找到root值,(inorder)左边就是左子树,(inorder)右边就是右子树
        // 然后在preorder中,数出与inorder中相同的个数即可
        int pos = inStart + count - 1;
        for (; pos >= inStart; --pos) {
            if (inOrder[pos] == rootValue) {
                break;
            }
        }
        int leftCount = pos - inStart;
        int rightCount = inStart + count - pos - 1;

        if (leftCount > 0) {
            int leftInStart = inStart;
            int leftPreStart = preStart + 1;
            root.left = dfs(leftCount, preOrder, leftPreStart, inOrder, leftInStart);
        }

        if (rightCount > 0) {
            int rightInStart = pos + 1;
            int rightPreStart = preStart + 1 + leftCount;
            root.right = dfs(rightCount, preOrder, rightPreStart, inOrder, rightInStart);
        }

        return root;
    }

我的前方是万里征途,星辰大海!!
原文地址:https://www.cnblogs.com/taoyuxin/p/13451004.html