前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >剑指 Offer(C++版本)系列:剑指 Offer 07 重建二叉树

剑指 Offer(C++版本)系列:剑指 Offer 07 重建二叉树

作者头像
我是管小亮
发布2021-07-20 11:23:14
2780
发布2021-07-20 11:23:14
举报
文章被收录于专栏:程序员管小亮的成长之路

同步GitHub在此 ? https://github.com/TeFuirnever/GXL-Skill-Tree

1、题干

代码语言:javascript
复制

重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。


例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7
 

限制:

0 <= 节点个数 <= 5000

通过次数158,941提交次数228,915


2、递归法

首先复习一下三种遍历:

  • 前序遍历:根节点 | 左子树 | 右子树;
  • 中序遍历:左子树 | 根节点 | 右子树;
  • 后序遍历:左子树 | 根节点 | 右子树;

然后,重建二叉树,需要知道根节点,左节点,右节点,那么就能重建,这就需要中序遍历,确定根节点所在位置,继而确定左右边界。

最后,当 left > right ,代表已经越过叶节点,此时返回 nullptr ;

算法流程:

  1. 首先初始化一个哈希表,保存中序遍历值对应的索引;
  2. 递归重建二叉树;
    1. 判断递归终止条件:无论是左子树还是右子树,left > right 都终止;
    2. 前序遍历的最左面结点是根节点的值 rootval ,根节点在中序遍历对应的即为根节点到左边界的长度 k;
    3. 建立根节点 root :new TreeNode(rootval);
    4. 构建左右子树:开启左右子树递归;

前序遍历左边界

前序遍历右边界

中序遍历左边界

中序遍历右边界

左子树

pl + 1

pl + 1 + len

il

k - 1

右子树

pl + 1 + len

pr

k + 1

ir

  1. 返回值:根节点 root ,作为上一层递归中根节点的左 / 右子节点;
代码语言:javascript
复制
//面试题07.重建二叉树
//标准做法
/**
 * 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:
 unordered_map<int, int> pos;
 TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
  int n = preorder.size();
  for (int i = 0; i<n; ++i) pos[inorder[i]] = i;
  return dfs(preorder, inorder, 0, n - 1, 0, n - 1);
 }
 
 TreeNode* dfs(vector<int>& preorder, vector<int>& inorder, int pl, int pr, int il, int ir)
 {
  if (pl>pr) return nullptr;
  if (il>ir) return nullptr;
  int rootval = preorder[pl];
  int k = pos[rootval];
  int len = k - il;
  auto root = new TreeNode(rootval);
  root->left = dfs(preorder, inorder, pl + 1, pl + 1 + len, il, k - 1);
  root->right = dfs(preorder, inorder, pl + 1 + len, pr, k + 1, ir);
  return root;
 }
};

4、复杂度

代码语言:javascript
复制
/*
时间复杂度:O(n)。对于每个节点都有创建过程以及根据左右子树重建过程。
空间复杂度:O(n)。存储整棵树的开销。
*/
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员管小亮 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、题干
  • 2、递归法
  • 4、复杂度
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档