[C++]LeetCode: 37 Construct Binary Tree from Preorder and Inorder Traversal
来源:互联网 发布:百度seo关键词优化 编辑:程序博客网 时间:2024/06/18 17:34
题目:
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
Anwser 1: 递归法
思路解析:这道题是树中比较有难度的题目,需要根据先序遍历和中序遍历来构造出树来。这道题看似毫无头绪,其实梳理一下还是有章可循的。下面我们就用一个例子来解释如何构造出树。
假设树的先序遍历是12453687,中序遍历是42516837。这里最重要的一点就是先序遍历可以提供根的所在,而根据中序遍历的性质知道根的所在就可以将序列分为左右子树。比如上述例子,我们知道1是根,所以根据中序遍历的结果425是左子树,而6837就是右子树。接下来根据切出来的左右子树的长度又可以在先序便利中确定左右子树对应的子序列(先序遍历也是先左子树后右子树)。根据这个流程,左子树的先序遍历和中序遍历分别是245和425,右子树的先序遍历和中序遍历则是3687和6837,我们重复以上方法,可以继续找到根和左右子树,直到剩下一个元素。可以看出这是一个比较明显的递归过程,对于寻找根所对应的下标。
算法最终相当于一次树的遍历,每个结点只会被访问一次,所以时间复杂度是O(n)。而空间我们需要建立一个map来存储元素到下标的映射,所以是O(n)。
Attention:
1. 注意helper函数各个参数的含义。sPre, ePre, sMid, eMid分别代表当前树的前序遍历起点/终点索引,中序遍历起点/终点索引。
2. 注意helper函数参数的传递值,最好画图确定(首先要确定每次构造树时的根的索引pos)。
3. pos代表中序遍历中子树根所在位置。
AC Code:
/** * 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 *buildTree(vector<int> &preorder, vector<int> &inorder) { if(!preorder.size() || !inorder.size()) return NULL; return buildTree_helper(preorder, inorder, 0, preorder.size()-1, 0, inorder.size() -1); }private: TreeNode* buildTree_helper(vector<int>& preorder, vector<int>& inorder, int sPre, int ePre, int sMid, int eMid){ if(sPre > ePre || sMid > eMid) return NULL; int pivot = preorder[sPre]; //找到中序遍历中子树根所在位置。 int pos; for(pos = sMid; pos <= eMid; pos++) { if(inorder[pos] == pivot) break; } TreeNode* root = new TreeNode(pivot); //pos-sMid代表新的左子树中节点个数,加上初始偏移sPre,得到新的ePre root->left = buildTree_helper(preorder, inorder, sPre + 1, sPre + (pos - sMid), sMid, pos - 1); root->right = buildTree_helper(preorder, inorder, sPre + (pos - sMid) + 1, ePre, pos + 1, eMid); return root; }};
Anwser 2: 非递归法
思路:(在未符合相等条件时)一边把前序遍历的结点构造成新结点左孩子(depth-first),同时把结点放进stack中,当碰到和中序遍历等值时,即左孩子先碰到(f 置1),紧接着会碰到根结点(f 置1),接下来前序遍历的值就是根的右孩子,可以根据flag将其放到根结点的右孩子处。
Attention: 注意前序遍历和中序遍历的先后顺序。注意在构造完右孩子后要把标记重置(f 要重置0)!!!
AC Code:
/** * 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 *buildTree(vector<int> &preorder, vector<int> &inorder) { if(!preorder.size()) return NULL; stack<TreeNode*> st; TreeNode* root, *t; int i, j, f; j = f = 0; root = new TreeNode(preorder[0]); st.push(root); i = 1; t = root; while(i < preorder.size()) { if(!st.empty() && st.top()->val == inorder[j]) { t = st.top(); st.pop(); j++; f = 1; } else { if(f == 0) { t->left = new TreeNode(preorder[i]); t = t->left; st.push(t); i++; } else { //记住要把f重置 f = 0; t->right = new TreeNode(preorder[i]); t = t->right; st.push(t); i++; } } } return root; }};
- *(leetcode) Construct Binary Tree from Preorder and Inorder Traversal (tree)
- LeetCode[Tree]: Construct Binary Tree from Preorder and Inorder Traversal
- [leetcode][tree] Construct Binary Tree from Preorder and Inorder Traversal
- [C++]LeetCode: 37 Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode: Construct Binary Tree from Preorder and Inorder Traversal
- [LeetCode]Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode Construct Binary Tree from Preorder and Inorder Traversal
- [Leetcode] Construct Binary Tree from Preorder and Inorder Traversal
- Leetcode: Construct Binary Tree from Preorder and Inorder Traversal
- [LeetCode] Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode Construct Binary Tree from Preorder and Inorder Traversal
- leetcode 109: Construct Binary Tree from Preorder and Inorder Traversal
- 【leetcode】Construct Binary Tree from Preorder and Inorder Traversal
- [LeetCode]Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode-Construct Binary Tree from Preorder and Inorder Traversal
- [leetcode] Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode - Construct Binary Tree from Preorder and Inorder Traversal
- [leetCode] Construct Binary Tree from Preorder and Inorder Traversal
- 编程语言的书,写“深入”、“高级”的通常都不值得看,但是说“入门”的却往往难度很大
- 摄像机标定(附源码)
- C++ rand,srand用法
- MINA框架 中JAVA NIO处理主要逻辑的processor线程
- (转)微软等数据结构+算法面试100题全部答案集锦
- [C++]LeetCode: 37 Construct Binary Tree from Preorder and Inorder Traversal
- Linux下区分物理CPU、逻辑CPU和CPU核数
- 归并排序算法研究
- 黑马程序员———基础视频中涉及的几个设计模式
- 认识高斯分布
- opencv学习笔记(2)
- Linux中部署web项目
- 让写代码变成简单的copy操作,代码生成器之一---------android,findViewById
- Android中this、super的区别