Leetcode 105. Construct Binary Tree from Preorder and Ignorer Traversal(C++版)
2017-03-27 17:06
549 查看
Given preorder and inorder traversal of a tree, construct the binary tree.
思路分析:
一个前序遍历序列和一个中序遍历序列可以唯一确定一颗二叉树。
1、确定树的根节点:设前序遍历序列存储在preorder,中序遍历序列存储在inorder。前序遍历序列的第一个数字preorder[0]就是根结点的值
2、求解树的子树:找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点边和右边都为空,则根节点已经为叶子节点。
3、递归求解树:将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。
内存超限制了。是由于上述代码中申请了左子树、右子树的vector。
那么我们不能重新申请内存,就需要在参数中加上一些索引来指明左右子树的前序序列和中序序列的范围。我们可以添加三个参数,第一个参数为子树的前序序列在总的前序序列中的起始索引,第二个参数为子树的中序序列在总的中序序列中的起始索引,第三个参数为子树的结点个数,也就是子树的前序序列/中序序列的长度。
通过。
感觉自己对这个不是很熟悉,于是又写了C版本的程序,可是。。可是。。runtime error。。不知道为什么会酱紫。。我也没有找出来哪儿错了,哪位大神知道我一下,帮我找找错误呀~~
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize) {
if(preorder == NULL || inorder == NULL || preorderSize != inorderSize)
return NULL;
int rootValue = preorder[0];
struct TreeNode *root = (struct TreeNode*) malloc(sizeof(struct TreeNode));
root -> val = rootValue;
root -> left = NULL;
root -> right = NULL;
//只有一个节点
if(preorderSize == 1){
if(*preorder == *inorder)
return root;
else{
// cerr << "invalid input" << endl;
exit(0);
}
}
//多于一个节点,查找根结点在中序序列中的位置index,根据该位置将树分成左子树和右子树
int index;
for(int i = 0; i < inorderSize; i ++){
if(preorder[0] == inorder[i]){
index = i;
break;
}
}
//index左边为树的左子树的中序序列,右边为树的右子树的中序序列
int size = inorderSize;
int leftInSize = index;
int rightInSize = size - index - 1;
root -> left = buildTree(&preorder[1],leftInSize , inorder, leftInSize );
root -> right = buildTree(&preorder[leftInSize + 1], rightInSize, &inorder[index + 1], rightInSize);
return root;
}
思路分析:
一个前序遍历序列和一个中序遍历序列可以唯一确定一颗二叉树。
1、确定树的根节点:设前序遍历序列存储在preorder,中序遍历序列存储在inorder。前序遍历序列的第一个数字preorder[0]就是根结点的值
2、求解树的子树:找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点边和右边都为空,则根节点已经为叶子节点。
3、递归求解树:将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。
/** * 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: int getRootIndex(vector<int>&preorder,vector<int> &inorder,int len1){ for(int i = 0; i < len1; i++){ if(preorder[0] == inorder[i])//前序遍历的第一个值即根结点的值,在中序序列中找此值即可找到根结点在中序序列中的位置 return i; } return -1; } TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { int len1 = preorder.size(); int len2 = inorder.size(); if(len1 <= 0 || len2 <= 0 || len1 != len2) return NULL; int rootValue = preorder[0];//前序遍历第一个数字即根结点的值 TreeNode* root = new TreeNode(rootValue);//根结点 //如果只有一个节点,则返回root //只有一个根结点时,遍历序列的长度为1,且值相等 if(len1 == 1 && len2 == 1 && preorder[0] == inorder[0]) return root; //在中序遍历序列中找到根结点的值 int index = getRootIndex(preorder, inorder, len1); vector<int> left_preorder, left_inorder, right_preorder, right_inorder; //构造左子树的前序序列和中序序列 for(int i = 0; i < index; i++){ left_preorder.push_back(preorder[i + 1]); left_inorder.push_back(inorder[i]); } //构造左子树的前序序列和中序序列。len1和len2是等长的,所以在同一个循环中即可。 for(int i = index + 1; i < len1; i++){ right_preorder.push_back(preorder[i]); right_inorder.push_back(inorder[i]); } root -> left = buildTree(left_preorder, left_inorder); root -> right = buildTree(right_preorder, right_inorder); return root; } };
Submission Result: Memory Limit Exceeded
内存超限制了。是由于上述代码中申请了左子树、右子树的vector。那么我们不能重新申请内存,就需要在参数中加上一些索引来指明左右子树的前序序列和中序序列的范围。我们可以添加三个参数,第一个参数为子树的前序序列在总的前序序列中的起始索引,第二个参数为子树的中序序列在总的中序序列中的起始索引,第三个参数为子树的结点个数,也就是子树的前序序列/中序序列的长度。
/** * 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: int getRootIndex(vector<int>&preorder,vector<int> &inorder,int len1){ for(int i = 0; i < len1; i++){ if(preorder[0] == inorder[i])//前序遍历的第一个值即根结点的值,在中序序列中找此值即可找到根结点在中序序列中的位置 return i; } return -1; } TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { int len1 = preorder.size(); int len2 = inorder.size(); if(len1 <= 0 || len2 <= 0 || len1 != len2) return NULL; return preInBuildTree(preorder, inorder, 0, 0, len1); } TreeNode *preInBuildTree(vector<int> &preorder, vector<int> &inorder,int preIndex,int inIndex, int size){ if(size <= 0) return NULL; int rootValue = preorder[preIndex];//前序遍历第一个数字即根结点的值 TreeNode* root = new TreeNode(rootValue);//根结点 //如果只有一个节点,则返回root //只有一个根结点时,遍历序列的长度为1,且值相等 if(size == 1 && preorder[preIndex] == inorder[inIndex]) return root; //在中序遍历序列中找到根结点的值 int index; for(int i = inIndex; i < inIndex + size ; i ++){//从开始索引处开始查找 if(preorder[preIndex] == inorder[i]){ index = i; break; } } //根据找到的中序遍历中的根结点,继续划分成左右子树 int leftSize = index - inIndex; int rightSize = size - leftSize - 1; //新的左子树的前序和中序序列起始索引为preIndex+1和inIndex //新的右子树的前序和中序序列起始索引为preIndex + 1 + leftSize和index+1 root -> left = preInBuildTree(preorder, inorder, preIndex + 1, inIndex, leftSize); root -> right = preInBuildTree(preorder, inorder, preIndex + 1 + leftSize, index + 1, rightSize); return root; } };
通过。
感觉自己对这个不是很熟悉,于是又写了C版本的程序,可是。。可是。。runtime error。。不知道为什么会酱紫。。我也没有找出来哪儿错了,哪位大神知道我一下,帮我找找错误呀~~
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize) {
if(preorder == NULL || inorder == NULL || preorderSize != inorderSize)
return NULL;
int rootValue = preorder[0];
struct TreeNode *root = (struct TreeNode*) malloc(sizeof(struct TreeNode));
root -> val = rootValue;
root -> left = NULL;
root -> right = NULL;
//只有一个节点
if(preorderSize == 1){
if(*preorder == *inorder)
return root;
else{
// cerr << "invalid input" << endl;
exit(0);
}
}
//多于一个节点,查找根结点在中序序列中的位置index,根据该位置将树分成左子树和右子树
int index;
for(int i = 0; i < inorderSize; i ++){
if(preorder[0] == inorder[i]){
index = i;
break;
}
}
//index左边为树的左子树的中序序列,右边为树的右子树的中序序列
int size = inorderSize;
int leftInSize = index;
int rightInSize = size - index - 1;
root -> left = buildTree(&preorder[1],leftInSize , inorder, leftInSize );
root -> right = buildTree(&preorder[leftInSize + 1], rightInSize, &inorder[index + 1], rightInSize);
return root;
}
相关文章推荐
- 【C++】【LeetCode】105. Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
- [Leetcode]105. Construct Binary Tree from Preorder and Inorder Traversal
- Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal (Medium) (cpp)
- LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
- Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal
- leetcode-java-105. Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal(从前序遍历和中序遍历构造二叉树)
- 【leetcode】105. Construct Binary Tree from Preorder and Inorder Traversal
- [LeetCode] 105. Construct Binary Tree from Preorder and Inorder Traversal
- [Leetcode]105. Construct Binary Tree from Preorder and Inorder Traversal@python
- LeetCode --- 105. Construct Binary Tree from Preorder and Inorder Traversal
- leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal
- 剑指offer 面试题6:重建二叉树(Leetcode105. Construct Binary Tree from Preorder and Inorder Traversal) 解题报告
- 105. Construct Binary Tree from Preorder and Inorder Traversal LeetCode
- leetCode 105.Construct Binary Tree from Preorder and Inorder Traversal (根据前序遍历和中序遍历构造二叉树)
- [LeetCode]problem 105. Construct Binary Tree from Preorder and Inorder Traversal
- [leetcode] 105.Construct Binary Tree from Preorder and Inorder Traversal
- LeetCode - 105. Construct Binary Tree from Preorder and Inorder Traversal
- <LeetCode OJ> 105. Construct Binary Tree from Preorder and Inorder Traversal