您的位置:首页 > 其它

105. Construct Binary Tree from Preorder and Inorder Traversal

2016-01-10 22:14 357 查看
Given preorder and inorder traversal of a tree, construct the binary tree.

Note:

You may assume that duplicates do not exist in the tree.

根据先序序列和中序序列构建改二叉树

思路:根据先序序列确定树的根值,在中续序列中根值左侧的序列的为左子树,右边的序列为右子树。然后再递归,依次根据先序序列确定左子树的根和右子树的根。递归终止开始回溯的条件:数组只有一个值的时候。

重点在于如何确定数组的上下限,以下是3个版本。

1.超时的版本,超时的原因是因为在确定两个数组的边界的时候,没有利用到树的结点的数量是固定的信息。每次花费了大量查找

#include<iostream>
#include<vector>
#include<string>
#include<stdlib.h>
#include<algorithm>
using namespace std;
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.empty())
return NULL;
int rootValue = preorder.front();
TreeNode* root = new TreeNode(rootValue);
//construct left child
if (preorder.front() != inorder.front()){//left child exist
vector<int> pre;
vector<int> in;
vector<int>::iterator it = find(inorder.begin(), inorder.end(), rootValue);
vector<int>::iterator it2;
vector<int>::iterator iter = preorder.begin() + 1;
for ( ; iter != preorder.end(); iter++){
it2 = find(inorder.begin(), inorder.end(), *iter);
if (it2 > it)
break;
}
in.assign(inorder.begin(), it);
pre.assign(preorder.begin() + 1, iter);
root->left = buildTree(pre, in);
}

//construct right child
if (preorder.front() != inorder.back()){//right child exist
vector<int> pre;
vector<int> in;
vector<int>::iterator it = find(inorder.begin(), inorder.end(), rootValue);
vector<int>::iterator it2;
vector<int>::iterator iter = preorder.begin() + 1;
for (; iter != preorder.end(); iter++){
it2 = find(inorder.begin(), inorder.end(), *iter);
if (it2 > it)
break;
}
in.assign(it+1, inorder.end());
pre.assign(iter, preorder.end());
root->right = buildTree(pre, in);
}

return root;
}

};

void travel(TreeNode* root){
if (root){
cout << root->val << endl;
travel(root->left);
travel(root->right);
}
}

int main()
{
Solution solution;
vector<int> preorder;
preorder.push_back(1);
preorder.push_back(2);
preorder.push_back(4);
preorder.push_back(3);
preorder.push_back(6);
preorder.push_back(7);
vector<int> inorder;
inorder.push_back(4);
inorder.push_back(2);
inorder.push_back(1);
inorder.push_back(6);
inorder.push_back(3);
inorder.push_back(7);
TreeNode* root;
root = solution.buildTree(preorder, inorder);
travel(root);
return 0;
}


2. 超内存的版本,Memory Limit Exceeded.
之前听说只要在递归里申请数组,一般都超内存的,看来果真是的。

class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.empty())
return NULL;
int rootValue = preorder.front();
TreeNode* root = new TreeNode(rootValue);
//construct left child
if (preorder.front() != inorder.front()){//left child exist
vector<int> pre;
vector<int> in;
vector<int>::iterator it = find(inorder.begin(), inorder.end(), rootValue);
in.assign(inorder.begin(), it);
pre.assign(preorder.begin() + 1, preorder.begin()+1+(it-inorder.begin()));
root->left = buildTree(pre, in);
}

//construct right child
if (preorder.front() != inorder.back()){//right child exist
vector<int> pre;
vector<int> in;
vector<int>::iterator it = find(inorder.begin(), inorder.end(), rootValue);
in.assign(it+1, inorder.end());
pre.assign(preorder.begin()+(it-inorder.begin())+1, preorder.end());
root->right = buildTree(pre, in);
}

return root;
}

};


3. 正确的版本Accepted 。为了不超内存,不能在递归函数里分配数组,所以传递的新变量就不能是新生成的数组。因此参数中要用下标来传递。

#include<iostream>
#include<vector>
#include<string>
#include<stdlib.h>
#include<algorithm>
using namespace std;

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) {
return constructTree(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
}

TreeNode* constructTree(vector<int>& preorder, vector<int>& inorder, int sPre, int ePre, int sIn, int eIn){
if (sPre > ePre || sIn > eIn){
return NULL;
}

int rootValue = preorder[sPre];
TreeNode* root = new TreeNode(rootValue);
int left_child_length =  find(inorder.begin(), inorder.end(), rootValue) - inorder.begin()-sIn;
root->left = constructTree(preorder, inorder, sPre + 1, sPre + left_child_length, sIn, sIn+left_child_length-1);
root->right = constructTree(preorder, inorder, sPre+left_child_length+1, ePre, sIn+left_child_length+1, eIn);
return root;
}

};

void travel(TreeNode* root){
if (root){
cout << root->val << endl;
travel(root->left);
travel(root->right);
}
}

int main()
{
Solution solution;
vector<int> preorder;
preorder.push_back(1);
preorder.push_back(2);
preorder.push_back(4);
preorder.push_back(3);
preorder.push_back(6);
preorder.push_back(7);
vector<int> inorder;
inorder.push_back(4);
inorder.push_back(2);
inorder.push_back(1);
inorder.push_back(6);
inorder.push_back(3);
inorder.push_back(7);
TreeNode* root;
root = solution.buildTree(preorder, inorder);
travel(root);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: