Construct Binary Tree from Preorder and Inorder Traversal

题目大意

    给出一棵二叉树的前序和中序遍历,构建出原来的二叉树(题目保证给定的节点值不会重复)

解题思路

   不得不说这题的思路确实是简单粗暴。众所周知,前序遍历的顺序是中左右,设其结果为Preorder,而中序遍历是左中右,设其结果为Inorder,那么可以知道前序遍历结果的首个节点位置k必为中间节点,那么在Inorder中找到该节点的位置kk,Inorder首节点到kk这一段为左子树,kk+1到Inorder的尾巴为右子树,使用递归重复上述过程重复建立树节点即可。

         另外一道已知中序和后序的题目也是同样的思路,只需要在截取遍历结果的时候稍加改动即可。

总结

     题目不难,思路也很清晰,重点就在于两个细节:

                   1、为避免OJ判断MLE,考虑传入STL的vector迭代器作为参数参与递归,因为在实际编译运行时,其实参需要一一入栈,如果将vector本身传递进函数,则每递归一次就要将vector入栈,因此将消耗大量的空间,因此使用迭代器指向其首位置传入能避免上述问题。

                   2、使用相对距离而不是绝对位置,每次从当前两个序列截取时一定要使用相对的变更长度而非直接取到数组的下标位置,因为两种序列的下标基址不在同一位置。

代码

//遍历store,返回elem元素的位置 
    int find(vector<int>::iterator store, int left, int right, int elem)
    {
        int i = 0;
        for (int i = left; i <= right; ++ i){
            if (elem == *(store+i))return i;    
        }    
        return -1;
    }
    
    void dfs(vector<int>::iterator A, int leftA, int rightA, vector<int>::iterator B, int leftB, int rightB, TreeNode *&cur)
    {
         if (leftA > rightA || leftB > rightB)return ;
         cur = new TreeNode(A[leftA]);
         if (leftA == rightA || leftB == rightB)return ;          
         int midA = find(A, leftA, rightA, *(B+leftB));
         int midB = find(B, leftB, rightB, *(A+leftA));
         dfs(A, leftA+1, leftA+midB-leftB, B, leftB, midB-1, cur->left);//注意这里用相对长度!! 
         dfs(A, leftA+midB-leftB+1,rightA, B, midB+1, rightB, cur->right);//注意这里用相对长度!!
	/*Construct Binary Tree from Inorder and Posteorder Traversal
	  dfs(A, leftA, midA-1, B, leftB, leftB+midA-leftA-1, cur->left); 
          dfs(A, midA+1,rightA, B, leftB+midA-leftA, rightB-1, cur->right);	*/
         return ;
    }
    TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) 
    {
             TreeNode *root = NULL;
             dfs( preorder.begin(), 0, preorder.size()-1, inorder.begin(), 0, inorder.size()-1, root);
             return root;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值