LeetCode106. 从中序与后序遍历序列构造二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
思路
以后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来在切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。
代码
/**
* 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:
TreeNode* dfs(vector<int>& inorder, int inorderBegin, int inorderEnd,
vector<int>& postorder, int postorderBegin, int postorderEnd)
{
if (postorderEnd - postorderBegin == 0) return nullptr;
int rootVal = postorder[postorderEnd - 1];
TreeNode* root = new TreeNode(rootVal);
if (postorderEnd - postorderBegin == 1) return root;
int index;
for (index = 0; index < inorderEnd && inorder[index] != rootVal; ++index);
int leftInorderBegin = inorderBegin;
int leftInorderEnd = index;
int rightInorderBegin = index + 1;
int rightInorderEnd = inorderEnd;
int leftPostorderBegin = postorderBegin;
int leftPostorderEnd = postorderBegin + index - inorderBegin;
int rightPostorderBegin = postorderBegin + index - inorderBegin;
int rightPostorderEnd = postorderEnd - 1;
root->left =
dfs(inorder, leftInorderBegin, leftInorderEnd, postorder, leftPostorderBegin, leftPostorderEnd);
root->right =
dfs(inorder, rightInorderBegin, rightInorderEnd, postorder, rightPostorderBegin, rightPostorderEnd);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
{
return dfs(inorder, 0 , inorder.size(), postorder, 0, postorder.size());
}
};
LeetCode105. 从前序与中序遍历序列构造二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
思路
与LeetCode106. 从中序与后序遍历序列构造二叉树思路相同,具体思路见代码。
代码
/**
* 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:
TreeNode* dfs(vector<int>& inorder, int inorderBegin, int inorderEnd,
vector<int>& preorder, int preorderBegin, int preorderEnd)
{
if (preorderEnd - preorderBegin == 0) return nullptr;
int rootVal = preorder[preorderBegin];
TreeNode* root = new TreeNode(rootVal);
if (preorderEnd - preorderBegin == 1) return root;
int index;
for (index = 0; index < inorderEnd && inorder[index] != rootVal; ++index);
int leftInorderBegin = inorderBegin;
int leftInorderEnd = index;
int rightInorderBegin = index + 1;
int rightInorderEnd = inorderEnd;
int leftPreorderBegin = preorderBegin + 1;
int leftPreorderEnd = preorderBegin + 1 + index - inorderBegin;
int rightPreorderBegin = preorderBegin + 1 + index - inorderBegin;
int rightPreorderEnd =preorderEnd;
root->left =
dfs(inorder, leftInorderBegin, leftInorderEnd, preorder, leftPreorderBegin, leftPreorderEnd);
root->right =
dfs(inorder, rightInorderBegin, rightInorderEnd, preorder, rightPreorderBegin, rightPreorderEnd);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
{
return dfs(inorder, 0, inorder.size(), preorder, 0, preorder.size());
}
};
LeetCode654. 最大二叉树
https://leetcode-cn.com/problems/maximum-binary-tree/
给定一个不含重复元素的整数数组 nums
。一个以此数组直接递归构建的 最大二叉树 定义如下:
- 二叉树的根是数组
nums
中的最大元素。 - 左子树是通过数组中 最大值左边部分 递归构造出的最大二叉树。
- 右子树是通过数组中 最大值右边部分 递归构造出的最大二叉树。
返回有给定数组 nums
构建的 最大二叉树 。
输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解释:递归调用如下所示:
- [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。
- [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。
- 空数组,无子节点。
- [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
- 空数组,无子节点。
- 只有一个元素,所以子节点是一个值为 1 的节点。
- [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
- 只有一个元素,所以子节点是一个值为 0 的节点。
- 空数组,无子节点。
思路
遍历数组找到最大值作为分割点,再对分割点的左数组和右数组进行递归操作。
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution
{
private:
TreeNode* dfs(vector<int>& nums, int left, int right)
{
if (right - left == 0) return nullptr;
//分割点下标:maxValueIndex
int maxValueIndex = left;
for (int i = left + 1; i < right; ++i)
{
if (nums[i] > nums[maxValueIndex])
{
maxValueIndex = i;
}
}
TreeNode* root = new TreeNode(nums[maxValueIndex]);
if (right - left == 1) return root;
//左闭右开:[left, maxValueIndex)
root->left = dfs(nums, left, maxValueIndex);
//左闭右开:[maxValueIndex + 1, right)
root->right = dfs(nums, maxValueIndex + 1, right);
return root;
}
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums)
{
return dfs(nums, 0, nums.size());
}
};