14. 构造二叉树
2022-05-28 00:43
1596 查看
title: 构造二叉树 , 看这一篇就足够! 思想:构造整棵树 = 根节点 + 构造左子树 + 构造右子树
📃 题目一描述
题目链接:从中序与后序遍历构造二叉树
🔔 解题思路
必须明确条件:给出一个数组的值中,是没有重复的数字的,即没用节点的数值是相同的!
画图分析:(图来自dong哥)
可以很明确得知:后续遍历数组中postEnd就是中点的值,通过中点的值我们就可以在中序遍历数组中找到中点的位置,从而分割出左子树,右子树,递归就可以完成构建;
class Solution { public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { return build(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1); } //都是不同的值组成,不存在“中”在左子树中出现的情况; TreeNode* build(vector<int>& inorder, int inStart, int inEnd, vector<int>& postorder, int postStart, int postEnd) { if (inStart > inEnd) return nullptr; int rootVal = postorder[postEnd]; int size = 0; for (int i = inStart; i <= inEnd; i++) { if (rootVal == inorder[i]) { // 找到中序遍历“左 中 右” 的 “中”; size = i - inStart; // 记录左的长度,需要使用其长度求其他下标 =》 因为起点不一定是从0开始,要用相对值 break; } } //构建中节点,左右子树 TreeNode *root = new TreeNode(rootVal); root->left = build(inorder, inStart, inStart + size - 1, postorder, postStart, postStart + size - 1); root->right = build(inorder, inStart + size + 1, inEnd, postorder, postStart + size, postEnd - 1); return root; } };
📃 题目二描述
题目链接:从前序与中序遍历构造二叉树
🔔 解题思路
同上,依据图来写代码即可:
class Solution { public: TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { return build(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1); } TreeNode* build(vector<int>& preorder, int preStart, int preEnd, vector<int>& inorder, int inStart, int inEnd) { if (preStart > preEnd) return nullptr; int rootVal = preorder[preStart]; int size = 0; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { size = i -inStart; break; } } // 开始构建树 TreeNode* root = new TreeNode(rootVal); root->left = build(preorder, preStart + 1, preStart + size, inorder, inStart, inStart + size - 1); root->right = build(preorder, preStart + size + 1, preEnd, inorder, inStart + size + 1, inEnd); return root; } };
📃 题目三描述
题目链接:根据前序和后序遍历构造二叉树
🔔 解题思路
这道题与前两道题的不同之处:通过前序和后序是无法确定唯一一颗二叉树的!
原因:看图
前序和后序只能确定中,无法确定左右的边界!可能压根就没有左指针或者右指针 例如:
preorder = [1,2,3], postorder = [3,2,1],而下图两种树结构都满足;
理解:我们假设前序遍历的第二个元素是左子树的根节点(左图),但实际上左子树有可能是空指针(右图),那么这个元素就应该是右子树的根节点。由于这里无法确切进行判断,所以导致了最终答案的不唯一。
这道题如何做:**①确定根节点,②将前序遍历数组中根节点后的下一位为左根节点(preStart + 1, 自己也快选定其他), ③在后序遍历数组中找到该左根节点的位置,从而分割左右子树;**如图:
代码:
class Solution { public: TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) { return build(preorder, 0, preorder.size() - 1, postorder, 0, postorder.size() - 1); } TreeNode* build(vector<int>& preorder, int preStart, int preEnd, vector<int>& postorder, int postStart, int postEnd) { if (preStart > preEnd) return nullptr; int rootVal = preorder[preStart]; if (preStart == preEnd) return new TreeNode(rootVal); int leftRootVal = preorder[preStart + 1]; int size = 0; for (int i = postStart; i <= postEnd; i++) { if (postorder[i] == leftRootVal) { size = i - postStart; break; } } //构建二叉树 TreeNode* root = new TreeNode(rootVal); root->left = build(preorder, preStart + 1, preStart + size + 1, postorder, postStart, postStart + size); root->right = build(preorder, preStart + size + 2, preEnd, postorder, postStart + size + 1, postEnd); return root; } };
优化建议:以上三题,均是不重复数组,可以用空间换时间的想法:可以采用哈希表记录 需要遍历的数组 对应的index, 这样在每次遍历的时候可以直接得到想要查询数的下标;
📃 题目四描述(简单练手题)
题目链接:最大二叉树
🔔 解题思路
根据构造树的思想,依题目构造即可
class Solution { public: TreeNode* constructMaximumBinaryTree(vector<int>& nums) { return build(nums, 0, nums.size() - 1); } TreeNode* build(vector<int>& nums, int start, int end) { if (start > end) return nullptr; int rootVal = INT_MIN; int index = 0; for (int i = start; i <= end; i++) { if (rootVal < nums[i]) { index = i; rootVal = nums[i]; } } //构建树 TreeNode* root = new TreeNode(rootVal); root->left = build(nums, start, index - 1); root->right = build(nums, index + 1, end); return root; } };
相关文章推荐
- 已知中序与后序,或者中序与先序,构造二叉树
- hduoj-5444【二叉树构造】
- 构造数组的MaxTree(二叉树)
- 1622-构造二叉树
- ural 1136. Parliament 二叉树构造和遍历
- python二叉树的构造和打印
- 如何构造二叉树
- 前序遍历和中序遍历树构造二叉树 查看运行结果
- lua构造完美二叉树
- lintcode- 前序遍历和中序遍历树构造二叉树-73
- 数据结构例程——二叉树的构造
- LeetCode 106: 从中序与后序遍历序列构造二叉树
- 第11周—项目1(2).1由后序序列和中序序列构造二叉树
- LeetCode1008先序遍历构造二叉树
- leetcode 105. 从前序与中序遍历序列构造二叉树(哈希)
- 基于python二叉树的构造和打印例子
- 14.Swift-构造过程Initialization
- LeetCode OJ 之 Construct Binary Tree from Inorder and Postorder Traversal (由二叉树的中序和后序序列构造二叉树)
- 第十一周 二叉树的构造
- LeetCode Construct Binary Tree from Preorder and Inorder Traversal(构造二叉树)