剑指 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);
        ...    
}

 

posted on 2020-07-22 19:14  BoysCryToo  阅读(91)  评论(0编辑  收藏  举报

导航