zoukankan      html  css  js  c++  java
  • 剑指 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
    ",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
    ",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);
            ...    
    }
  • 相关阅读:
    5. 添加后台管理页面
    4. 整合MyBatis
    3. 添加多个控制器
    2. 引入springmvc
    1. 开篇-springboot环境搭建
    去除angularjs路由的显眼的#号
    EasyUI DataGrid 分页实现示例
    等待对话框实现
    使用Struts2搭建登录注册示例
    观察者模式
  • 原文地址:https://www.cnblogs.com/BoysCryToo/p/13362654.html
Copyright © 2011-2022 走看看