1. 程式人生 > >【劍指offer】重建二叉樹 ★★★

【劍指offer】重建二叉樹 ★★★

題目描述:

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。

解題思路:

知道整體思路是:

在二叉樹的前序遍歷序列中,第一個數字總是樹的根結點的值。但在中序遍歷序列中,根結點的值在序列的中間,左子樹的結點的值位於根結點的值的左邊,而右子樹的結點的值位於根結點的值的右邊。因此我們需要掃描中序遍歷序列,才能找到根結點的值。如題目給出的序列,前序遍歷中的第一個數字1就是根結點的值。掃描中序遍歷序列,就能確定根結點的值的位置。根據中序遍歷的特點,在根結點的值1前面的3個數字都是左子樹結點的值,位於1後面的數字都是右子樹結點的值。這樣我們就在前序遍歷和中序遍歷兩個序列中,分別找到了左右子樹對應的子序列。因此,可以用同樣的方法去構建左右子樹。也就是說,接下來的事情可以用遞迴的方法去完成。

也就是在前序遍歷序列中找根節點,然後根據根節點到中序遍歷序列中劃分左右子樹兩部分,然後分別在左右子樹中遞迴重複上述過程。

但是每次一遇到遞迴問題思路就好亂啊,腦子完全纏繞在一起理不清啊啊啊~~~

所以,我就每次在做題之前都先把思路畫一畫,這樣寫程式的時候就清楚一些了:

public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        TreeNode root = new TreeNode(pre[0]);
        int len = pre.length;
        if(len == 1){
            root.left = null;
            root.right = null;
            return root;
        }
        else {
            // 在中序遍歷序列中找到根節點的位置i
            int i;
            for (i=0;i<len;i++){
                if (in[i] == root.val) break;
            }
            //左子樹,從pre[1]開始
            int [] lpre = new int[i];
            int [] lin = new int [i];
            if(i == 0){             //當前中序序列的第一個為根節點,即不存在有左節點
                root.left = null;
            }
            else{
                for (int j=0;j<i;j++){
                    lpre[j] = pre[j+1];
                    lin[j] = in[j];
                }
                root.left = reConstructBinaryTree(lpre,lin);
            }
            //右子樹,從pre[i+1]開始
            int [] rpre = new int[len-i-1];
            int [] rin = new int[len-i-1];
            if (len-i-1 == 0){          //當前中序序列的最後一個為根節點,即不存在有右節點
                root.right = null;
            }
            else{
                for (int j=0;j<len-i-1;j++){
                    rpre[j] = pre[j+i+1];
                    rin[j] = in[j+i+1];
                }
                root.right = reConstructBinaryTree(rpre,rin);
            }
            return root;
        }
    }

提醒我自己:一定要記得對各種null做判斷!