根据一棵树的前序遍历与中序遍历构造二叉树(C++)


题目来源: 力扣…根据一棵树的前序遍历与中序遍历构造二叉树

1. 题目描述

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例:
在这里插入图片描述

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

提示:

1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均 无重复 元素
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列

2. 题目解析

我们知道,前序遍历提供了节点的根节点顺序,而中序遍历提供了节点在树中的相对位置。通过结合这两个遍历序列,我们可以唯一确定一棵二叉树。因此,解这道题目的核心思想是:前序遍历确定根,中序遍历根据前序遍历确定的根划分左右子树!!!

画个图理解一下:
在这里插入图片描述
代码如下:

TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int& rooti, int left, int right)
{
	//中序区间不存在
    if (left > right) return nullptr;
     int i = 0;
     //在中序区间找当前根,划分左右子树
     while (preorder[rooti] != inorder[i]) i++;
     TreeNode* root = new TreeNode(preorder[rooti++]);
     //递归构建左右子树
     // [left, i - 1] i [i + 1 right]
     root->left = _buildTree(preorder, inorder, rooti, left, i - 1);
     root->right = _buildTree(preorder, inorder, rooti, i + 1, right);
     return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
{
	int i = 0;//当前树的根的位置
    return _buildTree(preorder, inorder, i, 0, inorder.size() - 1);
}

至此,本片文章就结束了,若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。

创作不易,白嫖不好,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

如果本篇博客有任何错误,请批评指教,不胜感激 !!!
在这里插入图片描述

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述: 输入一棵二叉树前序遍历中序遍历,输出该二叉树的后序遍历。 解题思路: 根据二叉树前序遍历中序遍历可以确定一棵二叉树前序遍历的第一个节点是根节点,根据中序遍历可以得到左子树和右子树的节点个数,从而可以将前序遍历中序遍历分成左子树和右子树的两部分,递归构建左子树和右子树。 递归终止条件为前序遍历中序遍历为空,此时返回空节点。 C++代码: ```cpp #include <iostream> #include <vector> #include <unordered_map> using namespace std; struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; class Solution { public: TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { unordered_map<int, int> map; for (int i = 0; i < inorder.size(); i++) { map[inorder[i]] = i; } return buildTree(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1, map); } private: TreeNode* buildTree(vector<int>& preorder, int preStart, int preEnd, vector<int>& inorder, int inStart, int inEnd, unordered_map<int, int>& map) { if (preStart > preEnd || inStart > inEnd) { return NULL; } int rootVal = preorder[preStart]; int rootIndex = map[rootVal]; int leftNodes = rootIndex - inStart; TreeNode* root = new TreeNode(rootVal); root->left = buildTree(preorder, preStart + 1, preStart + leftNodes, inorder, inStart, rootIndex - 1, map); root->right = buildTree(preorder, preStart + leftNodes + 1, preEnd, inorder, rootIndex + 1, inEnd, map); return root; } }; void postorder(TreeNode* root) { if (root == NULL) { return; } postorder(root->left); postorder(root->right); cout << root->val << " "; } int main() { vector<int> preorder = {1, 2, 4, 5, 3, 6}; vector<int> inorder = {4, 2, 5, 1, 3, 6}; Solution solution; TreeNode* root = solution.buildTree(preorder, inorder); postorder(root); return 0; } ``` 输出结果为: ``` 4 5 2 6 3 1 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值