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

劍指 Offer 07. 重建二叉樹-7月22日

題目

劍指 Offer 07. 重建二叉樹

我的思路

遞迴的思想來解決:
重複性的問題是:
輸入preorder 和 inorder字串
在inorder字串中找到preorder首字元,把inorder字串劈成2個子字串
以inorder第一個子符串中的最後一個字元為邊界,把preorder字串也分成兩個(用子字串長度加上preorder第一個子串的起始位置即可)
再執行兩次:create(root,pre1,in1);create(root,pre2,in2);

我的實現

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 
*/ class Solution { public: void create(TreeNode* root,int pre_begin,int pre_end,int in_begin,int in_end,vector<int>& preorder, vector<int>& inorder){ printf("%d\n",inorder[in_begin]); int root_val = preorder[pre_begin]; //root->val = root_val; if
(pre_begin==pre_end) return;//遞迴出口條件 //在中序字串中找到root_val,劈成兩半 int i,k,temp; int j = pre_begin; for(i=in_begin;i<=in_end;i++){ if(inorder[i]==root_val) break; } printf("i=%d\n",i); if(i>in_begin)//存在左子樹 { //在前序子串中找到中序被劈開處前一個字元
temp = pre_begin; j = pre_begin+i-in_begin; root->left=new TreeNode(preorder[pre_begin+1]); printf("create:%d--%d,%d--%d",pre_begin+1,j,in_begin,i-1); create(root->left,pre_begin+1,j,in_begin,i-1,preorder,inorder); } if(i<in_end)//存在右子樹 { //在前序子串中找到中序被劈開處後一個字元 root->right=new TreeNode(preorder[j+1]); create(root->right,j+1,pre_end,i+1,in_end,preorder,inorder); } } TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { if(preorder.size()==0)return NULL; TreeNode * root = new TreeNode(preorder[0]); //root->left=NULL;root->right=NULL; create(root,0,preorder.size()-1,0,preorder.size()-1,preorder,inorder); return root; } }; /* 遞迴的思想來解決: 重複性的問題是: 輸入preorder 和 inorder字串 在inorder字串中找到preorder首字元,把inorder字串劈成2個子字串 以inorder第一個子符串中的最後一個字元為邊界,把preorder字串也分成兩個(用子字串長度加上preorder第一個子串的起始位置即可) 再執行兩次:create(root,pre1,in1);create(root,pre2,in2); */

拓展學習

另一種思路(迭代)

轉自官方題解

前序遍歷的第一個元素是根,可以把中序遍歷字串劈開,分成左子樹和右子樹,很直觀。

而中序遍歷的第一個元素,是樹的最左下節點。也可以看做是把前序遍歷字串劈開,分成從根一路左下到最左下節點 和 非這一路的子串。藉助棧,處理!

比較難理解!

陣列傳參學會用迭代器

TreeNode* recursionBuild(vector<int>::iterator preBegin, vector<int>::iterator preEnd,vector<int>::iterator inBegin, vector<int>::iterator inEnd )
    {
        ...    
        recursionBuild(preBegin+1,preBegin+1+(root-inBegin),inBegin,root);
        ...    
}