劍指Offer-4.重建二叉樹(C++/Java)

題目:

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

分析:

根據二叉樹的前序和中序遍歷,重建二叉樹。數組

咱們知道:spa

前序遍歷:根節點,左子樹,右子樹。code

中序遍歷:左子樹,根節點,右子樹。blog

後序遍歷:左子樹,右子樹,根節點。遞歸

能夠發現,前序遍歷的第一個數即是整個數的根節點,而這個數在中序遍歷中,又將數組分紅兩部分,其中左邊即是左子樹,右邊是右子樹,根據劃分出來的左右子樹,咱們又能夠返回前序遍歷,去查看左右子樹數組中的第一個元素,這樣就能夠遞歸求解這個問題了。索引

咱們要記錄好每次遞歸執行時的序列索引,這樣有利於咱們求解子問題須要數組的索引,前序遍歷數組的左右索引記爲leftPre,rightPre,中序遍歷數組的左右索引是leftIn和rightIn。get

則左子樹的前序遍歷數組左索引是leftPre+1,由於leftPre指的元素是root。io

左子樹的前序遍歷數組右索引是leftPre+flag-leftIn,其中flag是root在中序遍歷數組中的索引,而flag-leftIn正好是左子樹元素的個數。class

左子樹的中序遍歷數組索引是leftPre和flag-1,由於flag是咱們找到的root元素,左邊天然就是新的中序遍歷數組了。

右子樹的前序遍歷數組左索引是leftPre+flag-leftIn+1,其實也就是左子樹的右索引加1,由於在前序遍歷中,左右子樹是相連的。rightPre天然就成了右索引。

右子樹的中序遍歷數組索引是flag+1和rightIn。

不過在求解中,每次都要在中序遍歷的數組中去查找根節點的索引,咱們能夠開始的時候將索引存進map中,須要的時候直接取,這樣能夠下降時間複雜度。

程序:

C++

class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        return helper(pre, vin, 0, pre.size()-1, 0, vin.size()-1);
    }
    TreeNode* helper(vector<int>& preorder, vector<int>& inorder, int leftPre, int rightPre, int leftIn, int rightIn){
        if(leftPre > rightPre)
            return nullptr;
        TreeNode* root = new TreeNode(preorder[leftPre]);
        if(leftPre == rightPre)
            return root;
        else{
            int i = leftIn;
            for(;i <= rightIn; ++i){
                if(inorder[i] == preorder[leftPre])
                    break;
            }
            root->left = helper(preorder, inorder, leftPre+1, leftPre+i-leftIn, leftIn, i-1);
            root->right = helper(preorder, inorder, leftPre+i+1-leftIn, rightPre, i+1, rightIn);
            return root;
        }
    }
};

Java

//use HashMap
import java.util.HashMap;
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        map = new HashMap<>();
        for(int i = 0; i < in.length; ++i){
            map.put(in[i], i);
        }
        return helper(pre, in, 0, pre.length-1, 0, in.length-1);
    }
    public TreeNode helper(int[] preorder, int[] inorder, int leftPre, int rightPre, int leftIn, int rightIn){
        if(leftPre > rightPre)
            return null;
        TreeNode root = new TreeNode(preorder[leftPre]);
        if(leftPre == rightPre)
            return root;
        else{
            int i = map.get(preorder[leftPre]);
            root.left = helper(preorder, inorder, leftPre+1, leftPre+i-leftIn, leftIn, i-1);
            root.right = helper(preorder, inorder, leftPre+i-leftIn+1, rightPre, i+1, rightIn);
            return root;
        }
    }
    private HashMap<Integer, Integer> map;
}
相關文章
相關標籤/搜索