297. 二叉树的序列化与反序列化 比较难的题目

# 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
        """
        res=''
        def dfs_help(root ):
            nonlocal  res
            if not root :
                if len(res)==0:
                    res +='N'
                    return 
                else:
                    res +=',N'
                    return
            if len(res)==0:# 定位是头节点
                res += str(root.val)
            else:
                res += f',{str(root.val)}' 
            dfs_help(root.left)
            dfs_help(root.right)
        dfs_help(root )
        return res 
    def deserialize(self, data):
        """Decodes your encoded data to tree.
        
        :type data: str
        :rtype: TreeNode
        """
        index =0
        nodes= data.split(',')
        def dfs_help(nodes):
            nonlocal index 
            if nodes[index]=='N':
                index +=1
                return None 
            node =TreeNode(int(nodes[index]))
            index +=1
            node.left= dfs_help(nodes)
            node.right=dfs_help(nodes)
            return node 
        res =dfs_help(nodes)
        return res 



    """
    该类包含将二叉树序列化为字符串,并将字符串反序列化为二叉树的方法。
    序列化/反序列化方法采用基于先序遍历 (Pre-order Traversal) 的深度优先搜索 (DFS)。
    """

    def serialize0(self, root: Optional[TreeNode]) -> str:
        """
        将二叉树编码(序列化)为一个用逗号分隔的字符串。
        使用先序遍历 (根-左-右) 的顺序。空节点用特殊字符 'N' 表示。

        :type root: TreeNode
        :rtype: str
        """
        # res 用于累积构建序列化后的字符串
        res = ''

        # 定义一个嵌套的 DFS 辅助函数来进行遍历和构建字符串
        def dfs_help(node: Optional[TreeNode]):
            # 使用 nonlocal 关键字允许内部函数修改外部函数定义的变量 res
            nonlocal res

            # 1. 基线条件:如果当前节点为空 (None)
            if not node:
                # 如果 res 当前为空 (意味着这是第一个节点,即整棵树为空)
                if len(res) == 0:
                    # 直接添加 'N'
                    res += 'N'
                    return
                else:
                    # 如果 res 不为空,说明这是某个节点的子节点为空,
                    # 需要先添加逗号分隔符,再添加 'N'
                    res += ',N'
                    return

            # 2. 处理当前节点 (根节点) - 先序遍历的核心
            # 如果 res 当前为空 (说明这是整棵树的根节点)
            if len(res) == 0:
                # 直接添加根节点的值 (转换为字符串)
                res += str(node.val)
            else:
                # 如果 res 不为空,说明这不是第一个节点,需要先加逗号分隔符
                res += f',{str(node.val)}' # 使用 f-string 添加逗号和节点值

            # 3. 递归处理左子树
            dfs_help(node.left)
            # 4. 递归处理右子树
            dfs_help(node.right)

        # 从根节点开始执行 DFS 序列化
        dfs_help(root)
        # 返回最终构建的序列化字符串
        return res

    def deserialize0(self, data: str) -> Optional[TreeNode]:
        """
        将之前编码(序列化)的字符串解码(反序列化)为二叉树。
        根据先序遍历的顺序重建树。

        :type data: str
        :rtype: TreeNode
        """
        # index 用于在 nodes 列表中跟踪当前应该处理哪个元素
        # 使用 nonlocal 允许嵌套函数修改它
        index = 0
        # 将输入的字符串按逗号分割成节点值(或'N')的列表
        nodes = data.split(',')

        # 定义一个嵌套的 DFS 辅助函数来进行递归构建树
        def dfs_help(nodes_list: List[str]) -> Optional[TreeNode]:
            # 使用 nonlocal 关键字允许内部函数修改外部函数定义的变量 index
            nonlocal index

            # 1. 处理空节点标记 'N'
            # 如果当前索引指向的元素是 'N'
            if nodes_list[index] == 'N':
                # 消耗掉这个 'N' (索引向后移动一位)
                index += 1
                # 返回 None,表示这里是一个空子树
                return None

            # 2. 创建当前节点
            # 根据当前索引处的字符串值创建一个新的 TreeNode。
            # 注意需要将字符串转换为整数。
            node = TreeNode(int(nodes_list[index]))

            # 3. 消耗掉当前节点的值 (索引向后移动一位)
            index += 1

            # 4. 递归构建左子树
            # 因为是先序遍历序列化的,所以接下来列表中的元素属于左子树。
            # 递归调用 dfs_help 会处理左子树的所有节点(包括其中的'N'),
            # 并正确地移动 index。
            node.left = dfs_help(nodes_list)

            # 5. 递归构建右子树
            # 当左子树的递归调用返回后,index 已经指向右子树的第一个元素(或'N')。
            # 递归调用 dfs_help 来构建右子树。
            node.right = dfs_help(nodes_list)

            # 6. 返回当前构建好的节点(及其已连接好的左右子树)
            return node

        # 从 nodes 列表的开头开始执行 DFS 反序列化
        root = dfs_help(nodes)
        # 返回构建好的整棵树的根节点
        return root

# Your Codec object will be instantiated and called as such:
# ser = Codec() # 创建序列化器实例
# deser = Codec() # 创建反序列化器实例
# root = ... # (假设这里有一个 TreeNode 对象)
# serialized_string = ser.serialize(root) # 将树序列化为字符串
# deserialized_root = deser.deserialize(serialized_string) # 将字符串反序列化回树
# ans = deserialized_root # 得到反序列化后的根节点
# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值