449. 序列化和反序列化二叉搜索树

分析

中、前序遍历还原法

初看时的做法可能是利用“中序遍历+前序遍历还原二叉树”的做法,在序列化时同时输出中序、前序遍历的字符串,以"|“相隔即可。反序列化时先以”|"取中、前序遍历字符串,再还原即可。

但这种做法的序列化消耗稍微较大,如果有n个节点,输出空间约有 2 n 2n 2n

遍历还原法

留意到二叉搜索树的特性是,左子树的节点都小于根节点,右子树节点都大于。所以:

  • 序列化时,只需要按前序遍历序列化即可。
  • 反序列化时,字符串首节点是根节点,从左向右遍历,小于根节点的都在左子树,而大于的都在右子树。

空节点标识法

遇到空节点时标识为"#"。具体做法略。

后序遍历+范围递归法

官方题解的递归思路很巧妙。它不像大家常规的做法,先搜索数组寻找数组中左右子树的分界点,而是定义值范围。

递归的含义可以理解为:给定一个节点数组,其队尾的若干元素是一棵子树,按后序遍历排列。你的递归函数规定了这个子树的值范围,如何将子树结构还原出来。

class Codec:
    def serialize(self, root: TreeNode) -> str:
        arr = []
        def postOrder(root: TreeNode) -> None:
            if root is None:
                return
            postOrder(root.left)
            postOrder(root.right)
            arr.append(root.val)
        postOrder(root)
        return ' '.join(map(str, arr))

    def deserialize(self, data: str) -> TreeNode:
        arr = list(map(int, data.split()))
        def construct(lower: int, upper: int) -> TreeNode:
            if arr == [] or arr[-1] < lower or arr[-1] > upper:
                return None
            val = arr.pop()
            root = TreeNode(val)
            root.right = construct(val, upper)
            root.left = construct(lower, val)
            return root
        return construct(-inf, inf)

本人答案与官方题解思路大体一致:
注意,deserialize对解码进行了特例判断:

if data == "":
	return []

这是因为对于空字符串""split(",")会返回节点列表。python split函数对split()和split(“,”)两种情况的行为是不同的。

class Codec:

    def serialize(self, root: TreeNode) -> str:
        """Encodes a tree to a single string.
        """
        res = []
        def dfs(root):
            if root is None:
                return
            dfs(root.left)
            dfs(root.right)
            res.append(root.val)
        
        dfs(root)
        res = list(map(str, res))
        return ",".join(res)
        

    def deserialize(self, data: str) -> TreeNode:
        """Decodes your encoded data to tree.
        """
        if data == "":
            return []
        nodes = data.split(",")
        nodes = list(map(int, nodes))
        def decode(low, high):
            if len(nodes) == 0 or nodes[-1] < low or nodes[-1] > high:
                return None
            root = TreeNode(nodes[-1])
            nodes.pop(-1)
            root.right = decode(root.val, high)
            root.left = decode(low, root.val)
            return root
        return decode(float("-inf"), float("inf"))

你可能感兴趣的:(数据结构与算法,leetcode,算法,职场和发展)