没啥说的,层次遍历,空节点存个特殊符号标记一下就好,重建树也是按层次BFS重建树。
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root)
{
string res("");
queue<TreeNode*> my_queue;
my_queue.push(root);
vector<string> vec;
while(!my_queue.empty())
{
TreeNode *cur=my_queue.front();
my_queue.pop();
if(cur==nullptr)
{
vec.push_back("null");
}
else
{
vec.push_back(to_string(cur->val));
my_queue.push(cur->left);
my_queue.push(cur->right);
}
}
while(!vec.empty() and vec.back()=="null")
{
vec.erase(vec.end()-1);
}
for (auto s:vec)
{
res+=s;
res+=",";
}
return res;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data)
{
if(data.empty())
{
return nullptr;
}
queue<TreeNode *> my_queue;
int le=0,ri=data.find(',',le); //le是节点信息开始位置,ri是紧接着的逗号位置
if(ri==-1)
{
return nullptr;
}
TreeNode *root=new TreeNode(stoi(data.substr(le,ri-le)));
my_queue.push(root);
le=ri+1;
ri=data.find(',',le);
while (ri!=-1)
{
TreeNode *cur_node=my_queue.front();
my_queue.pop();
//左孩子
string p=data.substr(le,ri-le);
if(p!="null")
{
TreeNode *left=new TreeNode(stoi(p));
cur_node->left=left;
my_queue.push(left);
}
//右孩子
le=ri+1;
ri=data.find(',',le);
if(ri==-1)
{
break;
}
p=data.substr(le,ri-le);
if(p!="null")
{
TreeNode* right=new TreeNode(stoi(p));
cur_node->right=right;
my_queue.push(right);
}
le=ri+1;
ri=data.find(',',le);
}
return root;
}
};
这题首先可以用297的代码去套,速度也差不多,但是没有利用二叉搜索树的性质,下面是一个利用搜索树性质的方法。
正常二叉树如果序列化为字符串,想再转化为原二叉树的话,除了按层次建树,需要中序、前序、后序中的至少两个,从而重建二叉树。但对于二叉搜索树,它的中序遍历序列是单调递增的,那么我们可以求出前序或者后序序列任意一个,对其排序就得到了中序序列。这样我们只需要一个前序or后序序列就可以完成二叉搜索树的重建。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string res;
stack<TreeNode*> sta;
TreeNode *p=root;
while(p or !sta.empty()){ //先序遍历
if(p){
res+=to_string(p->val);
res+="#";
sta.push(p);
p=p->left;
}
else{
p=sta.top()->right;
sta.pop();
}
}
return res;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
vector<int> preorder,midorder;
int i=0,j;
while(i<data.size()){
j=data.find('#',i);
preorder.push_back(stoi(data.substr(i,j-i)));
i=j+1;
}
midorder=preorder;
sort(midorder.begin(),midorder.end());
return helper(preorder,0,preorder.size()-1,midorder,0,midorder.size()-1);
}
TreeNode* helper(vector<int>& pre,int le_pre,int ri_pre,vector<int>& mid,int le_mid,int ri_mid){
if(le_pre>ri_pre or ri_pre>=pre.size() or ri_mid>=mid.size()){
return 0;
}
TreeNode* root=new TreeNode(pre[le_pre]);
int p=find(mid.begin()+le_mid,mid.begin()+ri_mid,pre[le_pre])-mid.begin();
//p是中序序列中根节点的下标
root->left=helper(pre,le_pre+1,le_pre+p-le_mid,mid,le_mid,p-1);
root->right=helper(pre,le_pre+1+p-le_mid,ri_pre,mid,p+1,ri_mid);
return root;
}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));