1. 程式人生 > >劍指offer 面試題:重建二叉樹

劍指offer 面試題:重建二叉樹

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

思路:二叉樹先序是根左右,中序 是左根右。所以先找到二叉樹的根節點,然後中序遍歷根節點左邊就是左子樹,右邊就是右子樹 (補充中序遍歷與其他任何一種遍歷都能唯一構造一顆二叉樹)

下面程式碼用遞迴寫得,注意先序的範圍(中序遍歷根節點左邊的節點一定都緊跟在 先序遍歷根節點後面,比如例子中中序遍歷根節點1左子樹3個節點,在前序遍歷中一定緊跟在前序遍歷後面,所以有i-inb+preb)和中序的範圍

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* restructtree(vector<int> pre,int preb,int pree,vector<int>
                          in,int inb,int ine)
    {
        if(preb>pree || inb>ine) return nullptr;
        TreeNode *head=new TreeNode(pre[preb]);
        int i;
        for(i=inb;i<=ine;++i)
            if(head->val == in[i])
                break;
        //下面i-inb表示根節點左子樹有多少個節點
        head->left=restructtree(pre,preb+1,preb+i-inb,in,inb,i-1);
        head->right=restructtree(pre,preb+i-inb+1,pree,in,i+1,ine);
        return head;
    }
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        return restructtree(pre,0,pre.size()-1,vin,0,vin.size()-1);
    }
};