题目描述:给出二叉树的先序遍历数组和中序遍历数组,构造原本的二叉树。
结构体为:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
基本思想是分治法,利用了先序遍历和中序遍历的特性。
先序遍历的特性是:第一个访问的结点一定是根结点。(即数组第一个值是根结点的值)
中序遍历的特性是:数组中的一个值(现结点),其左边的全部是现结点的左子树中的值,右边的全部是现结点的右子树中的值。
具体做法是:
driver
,其作用是正确地构造二叉树并返回二叉树的根结点。driver
(也就是递归),中序数组索引大于index的子数组也同样递归地用于driver
函数。class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return driver(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
}
TreeNode* driver(vector<int>& preorder, vector<int>& inorder, int p_lo, int p_hi, int i_lo, int i_hi) {
// 递归的边界,子树为空或着只有一个结点
if (p_lo > p_hi) return NULL;
if (p_lo == p_hi) return new TreeNode(preorder[p_lo]);
int node_val = preorder[p_lo];
int index_in = this->find(inorder, i_lo, i_hi, node_val);
int pre_left_len = index_in - i_lo;
TreeNode* node = new TreeNode(node_val);
// preorder[p_lo+1 ... p_lo+pre_left_len]是先序数组中与现结点左子树对应的部分。
// inorder[i_lo ... index_in-1]是中序数组中与现结点左子树对应的部分。
node->left = driver(preorder, inorder, p_lo + 1, p_lo + pre_left_len, i_lo, index_in - 1);
node->right = driver(preorder, inorder, p_lo + pre_left_len + 1, p_hi, index_in + 1, i_hi);
return node;
}
int find(vector<int>& vec, int low, int high, int val) {
for (int i = low; i <= high; ++i) {
if (vec[i] == val) return i;
}
return -1;
}
};
题目描述:给出中序数组和后序数组,构造原二叉树。
做法与105题相似,不再赘述。
代码如下:
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return driver(postorder, inorder, 0, postorder.size() - 1, 0, inorder.size() - 1);
}
TreeNode* driver(vector<int>& postorder, vector<int>& inorder, int p_lo, int p_hi, int i_lo, int i_hi) {
if (p_lo > p_hi) return NULL;
if (p_lo == p_hi) return new TreeNode(postorder[p_hi]);
int node_val = postorder[p_hi];
int index_in = this->find(inorder, i_lo, i_hi, node_val);
int pre_left_len = index_in - i_lo;
TreeNode* node = new TreeNode(node_val);
node->left = driver(postorder, inorder, p_lo, p_lo + pre_left_len - 1, i_lo, index_in - 1);
node->right = driver(postorder, inorder, p_lo + pre_left_len, p_hi - 1, index_in + 1, i_hi);
return node;
}
int find(vector<int>& vec, int low, int high, int val) {
for (int i = low; i <= high; ++i) {
if (vec[i] == val) return i;
}
return -1;
}
};