LeetCode297. 二叉树的序列化与反序列化+37:序列化二叉树(剑指offer第2版)

36 篇文章 0 订阅
13 篇文章 0 订阅

一、题目描述

https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/

请实现两个函数,分别用来序列化和反序列化二叉树

二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。

序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

二、代码详解(二叉树见上图)

力扣版

2.1 BFS(层序遍历:O(N)、O(N))

  • 序列化后的字符串: 1,2,3,4,#,5,6,#,#,#,#,#,#
  • 反序列化后的根节点值: 1
# Definition for a binary tree node.
class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
from collections import deque

class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.

        :type root: TreeNode
        :rtype: str
        """
        if not root:
            return ""
        res = []
        queue = deque([root])
        while queue:
            node = queue.popleft()
            if node != None:
                queue.append(node.left)
                queue.append(node.right)
                res.append(str(node.val))
            else:
                res.append("#")

        return ",".join(res)

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        if data == '':  # 必须加,不然ac不了
            return None
        datas = data.split(",")  # str.split
        # print(type(datas))  # <class 'list'>

        idx = 0
        val = datas[idx]

        if val == "#":
            return None

        root = TreeNode(int(val))  # 根节点
        queue = deque([root])

        while queue:
            node = queue.popleft()

            idx += 1
            val = datas[idx]
            if val != "#":
                node.left = TreeNode(int(val))
                queue.append(node.left)

            idx += 1
            val = datas[idx]
            if val != "#":
                node.right = TreeNode(int(val))
                queue.append(node.right)
        return root

# Your Codec object will be instantiated and called as such:

pRoot1 = TreeNode(1)
pRoot2 = TreeNode(2)
pRoot3 = TreeNode(4)
pRoot4 = TreeNode(3)
pRoot5 = TreeNode(5)
pRoot6 = TreeNode(6)

pRoot1.left = pRoot2
pRoot1.right = pRoot4

pRoot2.left = pRoot3

pRoot4.left = pRoot5
pRoot4.right = pRoot6

codec = Codec()

serializeStr = codec.serialize(pRoot1)
print('序列化后的字符串:', serializeStr)
print('反序列化后的根节点值:', codec.deserialize(serializeStr).val)
# 序列化后的字符串: 1,2,3,4,#,5,6,#,#,#,#,#,#
# 反序列化后的根节点值: 1

2.2 DFS(前序遍历)

  • 序列化后的字符串: 1,2,4,#,#,#,3,5,#,#,6,#,#
  • 反序列化后的根节点值: 1
# 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):  # preOrder
            if node:
                retList.append(str(node.val))
                dfs(node.left)
                dfs(node.right)
            else:
                retList.append("#")

        retList = []
        dfs(root)
        return ",".join(retList)

    def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        retList = data.split(',')
        if retList == []:
            return None

        def dfs():
            rootVal = retList[0]
            del retList[0]
            if rootVal == '#':
                return None
            node = TreeNode(int(rootVal))

            node.left = dfs()
            node.right = dfs()
            return node

        root = dfs()
        return root


    # 迭代器iter、next写法
    # def deserialize(self, data):
    #     """Decodes your encoded data to tree.
    #
    #     :type data: str
    #     :rtype: TreeNode
    #     """
    #
    #     def dfs():  # dePreOrder
    #         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()


迭代器写法:实现反序列化

iter() 函数用来生成迭代器 https://www.runoob.com/python/python-func-iter.html

next() 返回迭代器的下一个项目。next() 函数要和生成迭代器的iter() 函数一起使用。https://www.runoob.com/python/python-func-next.html

# Your Codec object will be instantiated and called as such:

pRoot1 = TreeNode(1)
pRoot2 = TreeNode(2)
pRoot3 = TreeNode(4)
pRoot4 = TreeNode(3)
pRoot5 = TreeNode(5)
pRoot6 = TreeNode(6)

pRoot1.left = pRoot2
pRoot1.right = pRoot4

pRoot2.left = pRoot3

pRoot4.left = pRoot5
pRoot4.right = pRoot6

codec = Codec()

serializeStr = codec.serialize(pRoot1)
print('序列化后的字符串:', serializeStr)
print('反序列化后的根节点值:', codec.deserialize(serializeStr).val)
# 序列化后的字符串: 1,2,4,#,#,#,3,5,#,#,6,#,#
# 反序列化后的根节点值: 1
  • 时间复杂度:在序列化和反序列化函数中,只访问每个节点一次,时间复杂度为 O(n),其中 n 是节点数,即树的大小。
  • 空间复杂度:在序列化和反序列化函数中,递归会使用栈空间,故渐进空间复杂度为 O(n)。

2.3 剑指版(DFS版)

# -*- coding:utf-8 -*-
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def Serialize(self, root):
        # write code here
        retList = []
        def preOrder(root):
            if root == None:
                retList.append('#')
                return

            retList.append(str(root.val))
            preOrder(root.left)
            preOrder(root.right)

        preOrder(root)
        return ' '.join(retList)

    def Deserialize(self, s):
        # write code here
        retList = s.split()
        if retList == []:
            return None

        def dePreOrder():
            rootVal = retList[0]
            del retList[0]
            if rootVal == '#':
                return None

            node = TreeNode(int(rootVal))

            leftNode = dePreOrder()
            rightNode = dePreOrder()

            node.left = leftNode
            node.right = rightNode

            return node

        pRoot = dePreOrder()
        return pRoot

pRoot1 = TreeNode(1)
pRoot2 = TreeNode(2)
pRoot3 = TreeNode(4)
pRoot4 = TreeNode(3)
pRoot5 = TreeNode(5)
pRoot6 = TreeNode(6)

pRoot1.left = pRoot2
pRoot1.right = pRoot4

pRoot2.left = pRoot3

pRoot4.left = pRoot5
pRoot4.right = pRoot6

s = Solution()
serializeStr = s.Serialize(pRoot1)
print('序列化后的字符串:', serializeStr)
print('反序列化后的根节点值:', s.Deserialize(serializeStr).val)

结果输出

序列化后的字符串: 1 2 4 # # # 3 5 # # 6 # #
反序列化后的根节点值: 1

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值