1. 程式人生 > 實用技巧 >劍指 Offer 07. 重建二叉樹

劍指 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;
    }