1. 解题思路
- 首先要明白 先序,中序,后序遍历(就是根左右,左根右,左右根)
- 样例先序遍历:[1,2,3,4,5,6,7] 中序遍历:[3,2,4,1,6,5,7]
1)起初范围就是整个先序列表和中序列表 ,先序的每个依次作为根节点
2)首先是1 对应中序数组下标[3],则3,2,4为左子树的内容,6,5,7为右分支的内容
/**
* 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* build(vector<int>& pre, int pre_left, int pre_right, vector<int>& vin, int vin_left, int vin_right) {
if (pre_left > pre_right) return nullptr;//判断该准备做根的节点存在
int value = pre[pre_left];//取出当前根的值
TreeNode* root = new TreeNode(value);//建立根节点
for (int i = vin_left; i <= vin_right; ++i) {//i从中序开始找的位置
if (vin[i] == value) {//找到先序根节点对应的中序位置
//这步 进行递归 寻找左右子树树
//根的左孩子指向节点为(先序根 )
//参数1.传递完整先序队列参数
//参数2. 本次先序根+1取新作为左子树根节点,但左子树其实不一定存在,需要划定右端点判断
//参数3. 限定左子树在先序的右端点,当前根节点位置+左子树个数(当前在中序位置-开始中序开始的位置)
//参数4.传递中序队列参数
//参数5. 中序左端点不变
//参数6. 中序变右边界(i-1)
root->left = build(pre, pre_left + 1, pre_left + i - vin_left, vin, vin_left, i - 1);
//根的右孩子指向节点为( )
//参数1.先序队列不变
//参数2. 下个先序右节点=本次先序根+几个左子树(i-中序初始位置)+1,但右子树其实不一定存在,需要划定右端点判断
//参数3. 限定右端点不变
//参数4.中序队列不变
//参数5. 中序变左端点(i+1)
//参数6. 中序右边界不变
root->right = build(pre, pre_left + i - vin_left+1, pre_right,vin, i + 1, vin_right);
break;
}
}
return root;
}
//返回头结点类型的 初始
//参数1.先序遍历数组
//参数2. 每次先序的定根节点 首次为0
//参数3. 匹配先序右端点
//参数4.中序遍历数组
//参数5. 中序开始找的位置
//参数6. 中序右端点
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
return build(pre, 0, pre.size() - 1, vin, 0, vin.size() - 1);//数组名
}
};