从前序与中序遍历序列构造二叉树
2020-01-14 09:27
267 查看
进入来看我这篇文章的小伙伴应该大都是遇见了leetcode中的105. 从前序与中序遍历序列构造二叉树或是106. 从中序与后序遍历序列构造二叉树,其实这两个题是明显的同意思路,如果一个题目没有思路,可以看看别人的解答,然后把另外一个当作练习,这也是极好的。
原理讲解
这两个题目的思路其实是和之前遍历二叉树的思路是一样的:分而治之。
在这样一个题目中,第一个重要的思路是前序(后序)在vector中的第一个值(最后一个值)是对应的一个父节点。
不得不提的是这个题目有这样一个假设:你可以假设树中没有重复的元素。所以以下我会用数字代指节点。
- 在刚拿到这个题目时,我们可以根据前序vector得出判断:3是一个父节点(如果无法理解这一步的话,我们需要复习一下先序遍历)。
- 根据1的结论,我们再由中序队列得出3这个节点的左边是[9],右边是[15,20,7](如果无法理解这一步的话,我们需要复习一下中序遍历)。
- 由2的结论,我们能够知道3这个节点左边的节点有1个,右边有3个。由此得到在前序的情况下:3这个节点左边是[9],右边是[20,15,7]。
=> 到这里我们得到了:
前序:[9] 前序:[20,15,7]
中序:[9] 中序: [15,20,7]
又回到了题目类似的条件。再如此循环,直到为空便可得出结果。
106. 从中序与后序遍历序列构造二叉树:源码
/** * 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* buildTree(vector<int>& inorder, vector<int>& postorder) { if(!inorder.size()) return nullptr; root = new TreeNode(NULL); _computeNode(inorder, postorder, root); return root; } private: void _computeNode(vector<int> inorder, vector<int> postorder, TreeNode* node) { if(inorder.size() == 0) { return; } else if (inorder.size() == 1) { node->val = inorder.back(); return ; } else { int cur = postorder.back(); node->val = cur; auto iter = find(inorder.begin(), inorder.end(), cur); if(iter == inorder.end()) return ; int rsize = inorder.end() - iter - 1; int lsize = iter - inorder.begin(); vector<int> lv = vector<int>(inorder.begin(), iter); vector<int> rv =vector<int>(iter + 1, inorder.end()); if(lv.size()) { node->left = new TreeNode(NULL); _computeNode(lv, vector<int>(postorder.begin(), postorder.begin() + lsize), node->left); } if(rv.size()) { node->right = new TreeNode(NULL); _computeNode(rv, vector<int>(postorder.end() - 1 - rsize, postorder.end() - 1), node->right); } } } TreeNode* root; };
——————
105. 从前序与中序遍历序列构造二叉树:源码
/** * 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* buildTree(vector<int>& preorder, vector<int>& inorder) { if(!preorder.size()) return nullptr; root = new TreeNode(NULL); _buildTree(preorder.begin(), preorder.end(), inorder.begin(), inorder.end(), root); return root; } private: TreeNode* root; void _buildTree(vector<int>::iterator preBegin, vector<int>::iterator preEnd, vector<int>::iterator inBegin, vector<int>::iterator inEnd, TreeNode* node) { if(preEnd - preBegin == 0) return ; else if(preEnd - preBegin == 1) { node->val = *preBegin; return ; }else { int cur = *preBegin; node->val = cur; auto iter = find(inBegin, inEnd, cur); if(iter == inEnd) return ; int lsize = iter - inBegin; int rsize = inEnd - iter - 1; if(lsize) { node->left = new TreeNode(NULL); _buildTree(preBegin + 1, preBegin + lsize + 1, inBegin, iter, node->left); } if(rsize) { node->right = new TreeNode(NULL); _buildTree(preBegin + lsize + 1, preEnd, iter + 1, inEnd, node->right); } } } };
总结
在106这个题目中,我用的是vector拷贝复制,性能消耗很大,但贵在思路看着更加清晰,跑起来88ms,比一些python的解决方案还要慢。在105这个题目中,我改正了这个错误,改用迭代器,28ms左右。可见拷贝这一行为的性能消耗之大,谨记。
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 105从前序与中序遍历序列构造二叉树
- leetcode-105- 从前序与中序遍历序列构造二叉树(construct binary tree from preorder and inorder traversal)-java
- 105. 从前序与中序遍历序列构造二叉树
- 从前序与中序遍历序列构造二叉树
- leetcode 105. 从前序与中序遍历序列构造二叉树(哈希)
- LeetCode-105.从前序与中序遍历序列构造二叉树(相关话题:深度优先搜索)
- leetcode 105. 从前序与中序遍历序列构造二叉树 c++实现
- LeetCode-105从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal)
- Leetcode 105.从前序与中序遍历序列构造二叉树
- 【Leetcode】105. 从前序与中序遍历序列构造二叉树
- LeetCode[98]验证二叉搜索树&[105]从前序与中序遍历序列构造二叉树
- LeetCode 105.从前序与中序遍历序列构造二叉树(C语言)
- 从前序与中序遍历序列构造二叉树
- leetcode 第105题(从前序与中序遍历序列构造二叉树) ,第106题(从中序与后序遍历序列构造二叉树)python解法(用时40ms)
- LeetCode 105. 从前序与中序遍历序列构造二叉树
- LeetCode OJ:Construct Binary Tree from Preorder and Inorder Traversal(从前序以及中序遍历结果中构造二叉树)
- 利用二叉树的中序遍历和后序遍历序列构造一个二叉树Search results for Construct Binary Tree from Inorder and Postorder Traversa
- 根据二叉树序列构造二叉树
- 根据前序遍历序列和中序遍历序列构造二叉树
- 由中序列和后序列来构造二叉树