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

传送门
题目要求序列化和反序列化一颗树,先抛开树结点的值,先解决如何确定一颗树的结构这个问题?第一时间想到的方法是用先中序或者是中后序的遍历结果来确定一棵树。再看看题目的限制,树的大小是1e4,结点值是1e3,最坏情况空间和时间复杂度是1e7级别的,勉强可行。再来思考如何确定每个节点的值这一问题,因为可能有重复的值,所以要正确储存一颗树的结构和值,需要对原树进行一点处理。具体方法如下:
序列化
用先序遍历的顺序结果对每一个节点进行重新赋值。在先序遍历的同时将节点上的原值存在一个字符串中。之后再进行中序遍历,储存中序遍历的结果在字符串中,有了这两个字符串即可进行反序列化。
反序列化
将上述两个字符串从data中分离出来,处理出先序遍历的结果和中序遍历的结果就可以用这题的方法得到结果105. 从前序与中序遍历序列构造二叉树
具体实现:

class Codec {
public:
    string mid,val;
    int tot = 0;
    string trans(int nn){// 将数字转为字符串要记得加入分隔符
        int n = abs(nn);
        string res = "";
        while(n){
            res += (n%10+'0');
            n /= 10;
        }
        if(nn < 0) res += '-';
        if(res.empty()) res += '0';
        reverse(res.begin(),res.end());
        res += '.';
        return res;
    }

    void dfsmid(TreeNode *now){ // 中序遍历
        if(now == NULL) return;
        dfsmid(now->left);
        mid += trans(now->val);
        dfsmid(now->right);
    }

    void dfspre(TreeNode *now){ // 先序遍历
        if(now == NULL) return;
        val += trans(now->val);
        now->val = tot++;
        dfspre(now->left);
        dfspre(now->right);
    }

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if(root == NULL) return "";
        dfspre(root);
        dfsmid(root);
        return mid + ',' + val;
    }

    vector<int> inorder;
    vector<int> preorder;
    vector<int> a;
    void solve(TreeNode *now,int l1,int r1,int l2,int r2){
        now->val = a[preorder[l2]];
        int pos = l1;
        for(int i = l1;i <= r1;++ i){
            if(preorder[l2] == inorder[i]){
                pos = i;
                break;
            }
        }
        if(l1 == r1) return;
        if(pos != l1){
            now->left = new TreeNode();
            solve(now->left,l1,pos-1,l2+1,l2+pos-l1);
        }
        if(pos != r1){
            now->right = new TreeNode();
            solve(now->right,pos+1,r1,l2+pos-l1+1,r2);
        }
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if(data.empty()) return NULL;
        bool flag = true,postive = true;
        int val = 0;
        int tot = 0;
        for(auto x:data){
            if(x == ',') flag = false;
            else if(x == '.'){
                if(!postive) val = -val;
                if(flag){
                    inorder.push_back(val);
                    preorder.push_back(tot++);
                }else{
                    a.push_back(val);
                }
                val = 0;
                postive = true;
            }
            else if(x == '-'){
                postive = false;
            }else{
                val = val*10+x-'0';
            }
        }
        int r = inorder.size();
        TreeNode *root = new TreeNode();
        solve(root,0,r-1,0,r-1);

        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值