Leetcode:106.从中序与后序序列遍历构造二叉树

Leetcode:106.从中序和后序序列遍历构造二叉树

  • 题目描述
  • 示例
  • 思路分析
  • 代码实现

题目描述

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

示例

示例1:
Leetcode:106.从中序与后序序列遍历构造二叉树_第1张图片

输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]

示例2:

输入:inorder = [-1], postorder = [-1]
输出:[-1]

思路分析

1: 用后序数组去创建根,然后遍历中序数组找到这个根,并记录这个根的下标.
2:通过这个根确定左右区间,左子树的根一定在左区间,右子树的根一定在右区间.
3:分别递归创建左右子树,并于根的左右结点相连接.
4:当左右子树创建完毕后,此时便会回溯到第一个函数栈帧中右子树递归完毕的位置,此时我们要返回根结点.

5: 这道题递归时返回上一层的条件即创建根的条件区间一定要合规.

注意:
1:从中序与后序序列遍历构造二叉树与中序与前序序列遍历构造二叉树不同的是,前序遍历的顺序遵循根–>左子树–>右子树,但是后序递归
的顺序为左子树–>右子树–>根.所以根据后序遍历,我们应该按照根–>右子树–>左子树的顺序创建树.
2: 遍历后序数数组时应该从后往前遍历创建根.

代码实现

class Solution {
public:
    TreeNode* _buildTree(vector<int>& inorder,vector<int>& postorder,int& posti,int inbegin,int intend)
    {
        //如果区间不符合条件,就不能再创建结点了。
        if(  inbegin > intend )
        {
            return nullptr;
        }
        //用后序的最后一个数去构建根.
        TreeNode* root = new TreeNode( postorder[posti] );
        //分割中序。
        --posti;
        int ini = inbegin;
       while(  ini <= intend  )
       {
           if( inorder[ini] == root->val )
           {
               break;
           }
           else
           {
               ++ini;
           }
        }
        //走到这里,就说明已经找到了,此时的区间为[inbegin,ini -1] ini [inti+1,intend],如果还有区间,
        //就说明还能继续向左递归,继续生成新的结点,如果区间不合格,就说明这个结点的左右子树都为空。
        root->right = _buildTree( inorder,postorder,posti,ini+1,intend );
        root->left = _buildTree( inorder,postorder,posti,inbegin,ini-1 );
        
        //左右遍历完,最后回溯到第一个root结点返回。
        return root;

    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder )
     {
        int posti = postorder.size()-1; 
        return _buildTree( inorder,postorder,posti,0,postorder.size()-1);
    }
};

你可能感兴趣的:(Leetcode,and,Niuke,leetcode)