[NeetCode 150] Serialize and Deserialize Binary Tree

Serialize and Deserialize Binary Tree

Implement an algorithm to serialize and deserialize a binary tree.

Serialization is the process of converting an in-memory structure into a sequence of bits so that it can be stored or sent across a network to be reconstructed later in another computer environment.

You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure. There is no additional restriction on how your serialization/deserialization algorithm should work.

Note: The input/output format in the examples is the same as how NeetCode serializes a binary tree. You do not necessarily need to follow this format.

Example 1:

复制代码
Input: root = [1,2,3,null,null,4,5]

Output: [1,2,3,null,null,4,5]

Example 2:

复制代码
Input: root = []

Output: []

Constraints:

复制代码
0 <= The number of nodes in the tree <= 1000.
-1000 <= Node.val <= 1000

Solution

A classic problem to rebuild a tree from serialized data is building a tree from pre-order traversal and in-order traversal. To do this, we can use recursion function to dive into the subsequence of pre-order and in-order traversal. The first node in pre-order sequence must the root, and the sequence on the left of root in the in-order sequence must be the left child tree of the root, so as the sequence on the right.

However, if we rethink about the process. Why cannot we rebuild the tree only from pre-order traversal? That's because we cannot divide the sequences of the left child tree and right child tree. So, we need to mark where the left child tree ends by adding none nodes. If meet none nodes in DFS, it is time to return. By doing this, we can know where the left child tree ends and start to DFS the right child tree.

Code

Rebuild from pre-order and in-order traversal.

py 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Codec:
    
    # Encodes a tree to a single string.
    def serialize(self, root: Optional[TreeNode]) -> str:
        if not root:
            return ''
        preo = []
        ino = []
        def inorder(node):
            if node.left:
                inorder(node.left)
            ino.append(str(node.val))
            if node.right:
                inorder(node.right)
        
        def preorder(node):
            preo.append(str(node.val))
            if node.left:
                preorder(node.left)
            if node.right:
                preorder(node.right)
        
        preorder(root)
        prestr = ','.join(preo)
        inorder(root)
        instr = ','.join(ino)
        return prestr+'#'+instr

        
    # Decodes your encoded data to tree.
    def deserialize(self, data: str) -> Optional[TreeNode]:
        if len(data) == 0:
            return None
        preorder = data.split('#')[0].split(',')
        inorder = data.split('#')[1].split(',')
        pre_map = {}
        in_map = {}
        for i in range(len(preorder)):
            pre_map[preorder[i]] = i
            in_map[inorder[i]] = i
        
        def dfs(prele, preri, inle, inri):
            if prele == preri:
                return TreeNode(int(preorder[prele]), None, None)
            if prele > preri:
                return None
            root = preorder[prele]
            inrootpos = in_map[root]
            ls_size = inrootpos-inle
            rs_size = inri-inrootpos
            ls = dfs(prele+1, prele+ls_size, inle, inrootpos-1)
            rs = dfs(prele+ls_size+1, preri, inrootpos+1, inri)
            return TreeNode(int(root), ls, rs)
        
        return dfs(0, len(preorder)-1, 0, len(inorder)-1)

Rebuild by adding none node to pre-order traversal.

py 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Codec:
    
    # Encodes a tree to a single string.
    def serialize(self, root: Optional[TreeNode]) -> str:
        res = []

        def dfs(node):
            if not node:
                res.append("N")
                return
            res.append(str(node.val))
            dfs(node.left)
            dfs(node.right)

        dfs(root)
        return ",".join(res)
        
    # Decodes your encoded data to tree.
    def deserialize(self, data: str) -> Optional[TreeNode]:
        vals = data.split(",")
        self.i = 0

        def dfs():
            if vals[self.i] == "N":
                self.i += 1
                return None
            node = TreeNode(int(vals[self.i]))
            self.i += 1
            node.left = dfs()
            node.right = dfs()
            return node

        return dfs()
相关推荐
Java 码农5 分钟前
Centos7 maven 安装
java·python·centos·maven
倔强青铜三1 小时前
苦练Python第63天:零基础玩转TOML配置读写,tomllib模块实战
人工智能·python·面试
浔川python社1 小时前
《网络爬虫技术规范与应用指南系列》(xc—3):合规实操与场景落地
python
B站计算机毕业设计之家1 小时前
智慧交通项目:Python+YOLOv8 实时交通标志系统 深度学习实战(TT100K+PySide6 源码+文档)✅
人工智能·python·深度学习·yolo·计算机视觉·智慧交通·交通标志
IT森林里的程序猿1 小时前
基于机器学习方法的网球比赛胜负趋势预测
python·机器学习·django
正牌强哥1 小时前
Futures_ML——机器学习在期货量化交易中的应用与实践
人工智能·python·机器学习·ai·交易·akshare
倔强青铜三2 小时前
苦练Python第62天:零基础玩转CSV文件读写,csv模块实战
人工智能·python·面试
郝学胜-神的一滴2 小时前
Effective Python 第43条:自定义容器类型为什么应该从 `collections.abc` 继承?
开发语言·python
银行数字化转型导师坚鹏2 小时前
如何设计优秀的企业微信私域运营实战培训方案
大数据·python·企业微信
jerryinwuhan3 小时前
最短路径问题总结
开发语言·人工智能·python