leetcode-297:二叉树的序列化与反序列化

简介: leetcode-297:二叉树的序列化与反序列化

题目

题目链接

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。



示例 1:

输入:root = [1,2,3,null,null,4,5]
输出:[1,2,3,null,null,4,5]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

输入:root = [1,2]
输出:[1,2]

解题

方法一:层序遍历

如:二叉树[1,2,3,null,null,4,null]序列化后的结果为[1,2,3,null,null,4,null,null,null],这样子反序列化过程中,索引i就不会超过范围

下面用"#"代表null部分

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Codec:
    def serialize(self, root):
        """Encodes a tree to a single string.
        :type root: TreeNode
        :rtype: str
        """
        if not root:
            return ""
        res = []
        queue = [root]
        while queue:
            cur =queue.pop(0)
            if cur:
                queue.append(cur.left)
                queue.append(cur.right)
                res.append(str(cur.val))
            else:
                res.append("#")
        return ",".join(res)
    def deserialize(self, data):
        """Decodes your encoded data to tree.
        :type data: str
        :rtype: TreeNode
        """
        if data == "":
            return None
        rec = data.split(',')
        root = TreeNode(rec[0])
        queue = [root]
        i = 1
        while queue:
            p = queue.pop(0)
            if rec[i] != "#":
                p.left = TreeNode(int(rec[i]))
                queue.append(p.left)
            i += 1
            if rec[i] != "#":
                p.right = TreeNode(int(rec[i]))
                queue.append(p.right)
            i += 1
        return root
# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))

注意要先p.left = TreeNode(int(rec[i]))queue.append(p.left),创建好节点,才能加入队列

c++ 写法

/**
 * 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:
    string join(vector<string>& vec){
        int n=vec.size();
        string res;
        for(int i=0;i<n;i++){
            res+=vec[i];
            if(i!=n-1) res+=",";
        }
        return res;
    }
    vector<string> split(string& s){
        vector<string> res;
        int i=0,n=s.size();
        while(i<n){
            int start=i;
            while(i<n&&s[i]!=',') i++;
            res.push_back(s.substr(start,i-start));
            i++;//跳过逗号
        }
        return res;
    }
    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if(root==nullptr) return "";
        queue<TreeNode*> q;
        q.push(root);
        vector<string> vec;
        while(!q.empty()){
            TreeNode* cur=q.front();
            q.pop();
            if(cur){
                q.push(cur->left);
                q.push(cur->right);
                vec.push_back(to_string(cur->val));
            }else{
                vec.push_back("#");
            }
        }
        string res=join(vec);     
        return res;
    }
    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if(data.size()==0) return nullptr;
        vector<string> vec=split(data);
        TreeNode* root=new TreeNode(stoi(vec[0]));
        queue<TreeNode*> q;
        q.push(root);
        int i=1;
        while(!q.empty()){
            TreeNode* cur=q.front();
            q.pop();
            if(vec[i]!="#"){
                cur->left=new TreeNode(stoi(vec[i]));
                q.push(cur->left);
            }
            i++;
            if(vec[i]!="#"){
                cur->right=new TreeNode(stoi(vec[i]));
                q.push(cur->right);
            }
            i++;
        }
        return root;
    }
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

方法二:先序遍历:使用递归

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Codec:
    def serialize(self, root):
        """Encodes a tree to a single string.
        :type root: TreeNode
        :rtype: str
        """
        def dfs(node):
            if node:
                vals.append(str(node.val))
                dfs(node.left)
                dfs(node.right)
            else:
                vals.append("#")
        vals = []
        dfs(root)
        return ",".join(vals)
    def deserialize(self, data):
        """Decodes your encoded data to tree.
        :type data: str
        :rtype: TreeNode
        """
        def dfs():
            v = next(vals)
            if v == "#":
                return None
            node = TreeNode(int(v))
            node.left = dfs()
            node.right = dfs()
            return node
        vals = iter(data.split(","))
        return dfs()
# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))
相关文章
|
23天前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
1月前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。
|
2月前
|
存储 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第9天】在Java的世界里,对象序列化是连接数据持久化与网络通信的桥梁。本文将深入探讨Java对象序列化的机制、实践方法及反序列化过程,通过代码示例揭示其背后的原理。从基础概念到高级应用,我们将一步步揭开序列化技术的神秘面纱,让读者能够掌握这一强大工具,以应对数据存储和传输的挑战。
|
2月前
【LeetCode 31】104.二叉树的最大深度
【LeetCode 31】104.二叉树的最大深度
20 2
|
1月前
|
存储 缓存 NoSQL
一篇搞懂!Java对象序列化与反序列化的底层逻辑
本文介绍了Java中的序列化与反序列化,包括基本概念、应用场景、实现方式及注意事项。序列化是将对象转换为字节流,便于存储和传输;反序列化则是将字节流还原为对象。文中详细讲解了实现序列化的步骤,以及常见的反序列化失败原因和最佳实践。通过实例和代码示例,帮助读者更好地理解和应用这一重要技术。
32 0
|
2月前
【LeetCode 43】236.二叉树的最近公共祖先
【LeetCode 43】236.二叉树的最近公共祖先
20 0
|
2月前
【LeetCode 38】617.合并二叉树
【LeetCode 38】617.合并二叉树
15 0
|
2月前
【LeetCode 37】106.从中序与后序遍历构造二叉树
【LeetCode 37】106.从中序与后序遍历构造二叉树
17 0
|
2月前
【LeetCode 34】257.二叉树的所有路径
【LeetCode 34】257.二叉树的所有路径
20 0
|
2月前
【LeetCode 32】111.二叉树的最小深度
【LeetCode 32】111.二叉树的最小深度
18 0