面试题37 序列化二叉树 python3 BFS+辅助队列

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

示例: 

你可以将以下二叉树:

    1
   / \
  2   3
     / \
    4   5

序列化为 "[1,2,3,null,null,4,5]"

本题的初始代码如下:

# 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 deserialize(self, data):
        """Decodes your encoded data to tree.
        
        :type data: str
        :rtype: TreeNode
        """
        

# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))

可见,序列化二叉树输入为一个根节点,输出为一个字符串;反序列化则是字符串输入,能够重建出二叉树。下面分别进行求解。

 

1. 序列化部分

输入:树的根节点;

输出:字符串。

思路

其实这非常像第32题:从上到下打印二叉树 Python3广度优先搜索

首先给出32题的代码。用的是辅助队列+BFS

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
 
class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        queue = []
        res = []
        queue.append(root)
        while queue:
            # for i in queue:
            node = queue[0]
            queue = queue[1:]
            res.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        
        if not queue:
            return res

对比32题和本题,可以看到,只要在32题的基础上:

  1. 将null的节点也保存到res中(目的是为了完整恢复树):
  2. 整个过程以字符串append的形式完成

就能够得到本题的求解。

总体来说,本题还是使用的层序遍历,具体而言就是BFS+辅助队列的方法。

更改后的代码如下:

# 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
        """
        # Definition for a binary tree node.
        if not root:
            return "[]"
        queue = []
        res = []
        queue.append(root)
        while queue:
            # for i in queue:
            node = queue[0]
            queue = queue[1:]
            if node:
                res.append(node.val)
                queue.append(node.left)
                queue.append(node.right)
            else:   # node 为 null
                res.append("null")
        print(str(res))
        return str(res)
        # return '[' + ','.join(res) + ']'
        

    def deserialize(self, data):
        """Decodes your encoded data to tree.
        
        :type data: str
        :rtype: TreeNode
        """
        if data == "[]": return
        vals, i = data[1:-1].split(','), 1
        print(vals)
        root = TreeNode(int(vals[0]))
        queue = collections.deque()
        queue.append(root)
        while queue:
            node = queue.popleft()
            # if vals[i][1] != "'":
            if vals[i] != "null":
                print(vals[i])
                node.left = TreeNode(int(vals[i]))
                queue.append(node.left)
            i += 1
            if vals[i] != "null":
                node.right = TreeNode(int(vals[i]))
                queue.append(node.right)
            i += 1
        return root

代码总是改不对...回去洗澡明天再改

 

之前的代码有问题的原因是在deserialize函数中,无论节点的值是否null,使用vals[i] != "null" 或者 vals[i] != 'null'都会判成True!因此始终会有如下错误:

ValueError: invalid literal for int() with base 10: " 'null'"
    node.left = TreeNode(int(vals[i]))
Line 54 in deserialize (Solution.py)
    return codec.deserialize(codec.serialize(root))
Line 72 in __helper__ (Solution.py)
    ret = __DriverSolution__().__helper__(
Line 85 in _driver (Solution.py)
    _driver()
Line 97 in <module> (Solution.py)

 原因是因为vals的键值实际上是这样的:

['1', ' 2', ' 3', " 'null'", " 'null'", ' 4', ' 5', " 'null'", " 'null'", " 'null'", " 'null'"]

因此可以把判断语句改成下面的样子:

if vals[i][1] != "'":

这是因为当vals[i]=”‘null’“时,vals[i][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
        """
        # Definition for a binary tree node.
        if not root:
            return "[]"
        queue = []
        res = []
        queue.append(root)
        while queue:
            # for i in queue:
            node = queue[0]
            queue = queue[1:]
            if node:
                res.append(node.val)
                queue.append(node.left)
                queue.append(node.right)
            else:   # node 为 null
                res.append("null")
        print(str(res))
        return str(res)
        # return '[' + ','.join(res) + ']'
        

    def deserialize(self, data):
        """Decodes your encoded data to tree.
        
        :type data: str
        :rtype: TreeNode
        """
        if data == "[]": return
        vals, i = data[1:-1].split(','), 1
        print(vals)
        root = TreeNode(int(vals[0]))
        queue = collections.deque()
        queue.append(root)
        while queue:
            node = queue.popleft()
            if vals[i][1] != "'":
            # if vals[i] != "null":
                print(vals[i])
                node.left = TreeNode(int(vals[i]))
                queue.append(node.left)
            i += 1
            if vals[i][1] != "'":
                node.right = TreeNode(int(vals[i]))
                queue.append(node.right)
            i += 1
        return root




# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))

结果

总结

思路仍旧是之前层序遍历的 BFS+辅助队列 的方法。

但是具体字符串操作时遇到了小问题,可以通过灵活改变判断方式来解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R.X. NLOS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值