劍指offer(java實現)第4題“重建二叉樹”-牛客網

zhuminChosen發表於2018-07-20

題目描述

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

時間限制:1秒 空間限制:32768K 熱度指數:382712

解答:

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {//思路:二叉樹的前序序列中第一個節點永遠是根節點root,中序序列中root所在的位置的左邊序列,都是當前root節點的左子樹,右邊都是root節點的右子樹,
    //因此,前序序列的root節點的下一位又是它的左子樹的根節點,同樣的規則適用於它的左右子樹,所以這裡我們可以用遞迴來實現
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if (pre == null || in == null || pre.length < 0 || in.length < 0 || pre.length != in.length) {//如果陣列為空或者兩個陣列的長度不一致,則輸入有誤
            System.out.println("陣列不能為空或者兩個陣列長度不一致");
            return null;
        }
        return reConstructBinaryTree(pre, in, 0, pre.length-1, 0, in.length-1);//之所以需要四個位置變數,是因為需要記錄前序序列的開始和結束位置,也要記錄
        //中序序列的開始和結束位置

    }
    //fStart表示前序序列開始節點, fStop表示前序序列結束節點,mStart表示中序序列開始節點,mStop表示中序序列結束節點
    public TreeNode reConstructBinaryTree(int [] pre, int [] in, int fStart, int fStop, int mStart, int mStop) {

        int rootValue = pre[fStart];
        TreeNode root = new TreeNode(rootValue);//先建立根節點
        root.left = null;
        root.right = null;
        //判斷是否是隻有一個節點
        if (fStart == fStop) {
            if (mStart == mStop) {
                return root;
            }else {
                System.out.println("兩個陣列輸入有誤");//其實上面做了判斷,這裡就不會走到else子句中來
                return null;
            }
        }
        int mm = mStart;//用一個變數記錄二叉樹的root節點在中序序列中的位置
        while (in[mm] != rootValue && mm <= mStop) {//直到在中序序列中找到root,或者遍歷完中序序列陣列
            ++mm;
        }
        if (in[mm] != rootValue) {//此時還不相等的話,說明中序序列中沒有此時的root
            System.out.println("中序序列中沒有與前序序列中確定的root節點相等的節點值");
            return null;
        }
        int mLengh = mm - mStart;//這裡一定要這樣寫,記錄移動的位置
        int fLeftSubTreeStop = fStart + mLengh;//前序序列當前的樹開始的節點位置+移動的位置就等於當前樹的子樹的結束位置

        if (mm > mStart) {
            root.left = reConstructBinaryTree(pre, in, fStart+1, fLeftSubTreeStop, mStart, mm-1);//(前序序列陣列,中序序列陣列,前序序列當前樹開始節點的後一位,
            //前序序列當前樹的子樹結束的位置,中序序列當前樹開始的位置,中序序列root位置的前一位)
        }
        if (mm < mStop) {  
            root.right = reConstructBinaryTree(pre, in, fLeftSubTreeStop+1, fStop, mm+1, mStop);//(前序序列陣列,中序序列陣列,前序序列當前樹的子樹結束的位置的前一位,
            //前序序列中當前樹結束的位置,中序序列root位置的後一位,中序序列中當前樹結束的位置
        }
        return root;
    }
}

 

相關文章