【力扣-二叉树】12、从中序与后序遍历序列构造二叉树(106)

「这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战

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

题目描述

根据一棵树的中序遍历与后序遍历构造二叉树。

注意: 你可以假设树中没有重复的元素。

例如,给出

中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
复制代码

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7
复制代码

解析

递归法

  • 步骤:
    • 1、判断数组大小是否为0,为0则表示空节点
    • 2、不为空,取后序遍历数组的最后一个元素(作为根节点)
    • 3、在中序遍历中找到后序遍历的最后一个元素
    • 4、切割中序数组,将中序数组分为中序左数组,中序右数组
    • 5、切割后序数组,得到后序左数组,后序右数组
    • 6、递归处理左区间和右区间

代码

class Solution
{
public:
   TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder)
   {
       return traversal(inorder, postorder);
   }

private:
   TreeNode *traversal(vector<int> &inorder, vector<int> &postorder)
   {
       // 1、判断数组大小是否为0,为0则表示空节点,直接返回空
       if (inorder.size() == 0)
       {
           return NULL;
       }
       // 取后序遍历的最后一个元素作为根节点
       int rootVal = postorder[postorder.size() - 1];
       // 设置根节点
       TreeNode *root = new TreeNode(rootVal);
       int splitPos;
       // 3、查找中序遍历的分割点
       for (splitPos = 0; splitPos < inorder.size(); splitPos++)
       {
           if (inorder[splitPos] == rootVal)
           {
               break;
           }
       }

       // 4、切割中序数组,分为左数组和右数组
       vector<int> inLeft(inorder.begin(), inorder.begin() + splitPos);
       vector<int> inRight(inorder.begin() + splitPos + 1, inorder.end());

       // 5、切割后序数组

       // 首先舍去最后一个元素
       postorder.resize(postorder.size() - 1);
       // 后序数组的切割根据已有条件来获得
       //      后序左数组的大小与中序左数组的大小相同,以此来找到切割点
       vector<int> postLeft(postorder.begin(), postorder.begin() + inLeft.size());
       vector<int> postRight(postorder.begin() + inLeft.size(), postorder.end());

       // 6、递归处理左区间和右区间
       root->left = traversal(inLeft, postLeft);
       root->right = traversal(inRight, postRight);

       return root;
   }
};
复制代码

Guess you like

Origin juejin.im/post/7032176291529015333