NC12 重建二叉树
Posted coder 靓仔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NC12 重建二叉树相关的知识,希望对你有一定的参考价值。
情景提要
牛客题解系列,按照题号顺序开始。
NC12 重建二叉树
01
题目描述
02
输入输出示例
输入:
[1,2,4,7,3,5,6,8],[4,7,2,1,5,3,8,6]
输出:
{1,2,3,4,#,5,6,#,7,#,#,8}
03
题目分析
本题和NC11有相似之处,核心思想都在于将数组切分成左右两部分,分别是左子树和右子树。
前序遍历: 中左右
中序遍历: 左中右
前序遍历的第一个元素是中,接着找到中序遍历的中,就可以将中序遍历数组划分为左右子树部分了。再利用左子树的前序遍历和中序遍历的数组的 长度相等,将前序遍历数组也划分为左右子树。
以题目描述为例:
step1:
前序遍历第一个元素的中为1,在中序遍历中找到1。
step2:
将中序遍历划分为左子树部分 [4,7,2],右子树部分:[5,3,8,6]。根据子树的不同遍历方式,数组的长度一定是相等的。左子树有3个,右子树有4个。划分前序遍历:
左子树 [2,4,7] 右子树 [3,5,6,8]
step3:重复到step1,分别构建左右子树。
编程中的一个小技巧是在递归函数中传递了数组的index。
03
代码实现
方法
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
return travel(pre,vin,0,pre.size()-1,0,vin.size()-1);
}
TreeNode* travel(vector<int>& pre,vector<int>& vin,int left1,int right1,int left2,int right2){
if(left1<right1){
TreeNode* root = new TreeNode(pre[left1]);
int mid;
for(mid=left2;mid<=right2;++mid){
if(vin[mid] == pre[left1]) break;
}
root->left = travel(pre,vin,left1+1,mid+left1-left2,left2,mid-1);
root->right = travel(pre,vin,right1-right2+mid+1,right1,mid+1,right2);
return root;
}
if(left1>right1) return nullptr;
if(left1 == right1) return new TreeNode(pre[left1]);
return nullptr;
}
};
04
总结
将数组不断切分,构造二叉树。
利用好前序遍历和中序遍历 "中" 元素位置的规律。
欢迎评论区留言讨论哦
以上是关于NC12 重建二叉树的主要内容,如果未能解决你的问题,请参考以下文章
NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段