297. 二叉树的序列化与反序列化+449. 序列化和反序列化二叉搜索树

297. 二叉树的序列化与反序列化

Q:

297. 二叉树的序列化与反序列化+449. 序列化和反序列化二叉搜索树_第1张图片

A:

没啥说的,层次遍历,空节点存个特殊符号标记一下就好,重建树也是按层次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;
    }
};

449. 序列化和反序列化二叉搜索树

Q:

297. 二叉树的序列化与反序列化+449. 序列化和反序列化二叉搜索树_第2张图片

A:

这题首先可以用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));

你可能感兴趣的:(Leetcode,c++,leetcode)