1. 程式人生 > >LeetCode 297 Hard 序列化/反序列化 二叉樹 Python

LeetCode 297 Hard 序列化/反序列化 二叉樹 Python

class Codec:
    """
    Solution Method
    參考答案給的解法是將二叉樹DFS序列化,然後對其反序列化
        這裡我最關鍵的是每想到這樣去反序列化,因為python傳參是引用傳參,通過這種先左後右雖然傳
    的都是同一個data,但是其實在左子樹和右子樹的建立中所看到的data是不一樣的,而序列化的建立過程中
    又是先左後右的,所以對一個序列用data[0]去建立節點反序列化是可以構造出原來的樹的,而且這種DFS的
    方法不會像我用層次遍歷一樣建立很多none的空節點,效率相對來說高
    ❗️❗️❗️:
        其實第105題根據先序和中序構造二叉樹也是巧妙地利用了這種傳參就是傳引用的特點,對二叉樹進行的
    處理,可以回顧一下
        再一個是序列化的過程中要注意引數傳遞的意義和值,string在左右子樹中就不能+=了,不然會錯,因為
    此時的string 已經是+=root.val了,底下既向下傳這個加後的string,又+=,就會重複導致出錯
    """

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

        def preorder(root, string):
            if root == None:
                string += 'None,'
            else:
                string += str(root.val) + ','
                string = preorder(root.left, string)
                string = preorder(root.right, string)
            return string

        return preorder(root, '')

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

        :type data: str
        :rtype: TreeNode
        """

        def reconstructTree(data):
            if data[0] == 'None':
                data.pop(0)
                return None
            root = TreeNode(int(data[0]))
            data.pop(0)
            root.left = reconstructTree(data)
            root.right = reconstructTree(data)
            return root

        return reconstructTree(data[:-1].split(','))


class CodecTLE:
    """
    My TLE Method
    最後一個超長的case沒過
    思路:
        我想的是利用滿二叉樹的性質,將二叉樹轉成一個滿二叉樹,這樣就可以通過下標進行左右孩子的索引然後把樹建立起來
        即 根為index的左孩子2*index,右孩子2*index+1
        這其中要處理好孩子節點可能是None,導致目標下標不存在,我這裡的做法就是用while去不停地append None,使得
        陣列的長度是能容納得下節點數的
        在佇列中存的就不僅僅是node了,還有node在滿二叉樹陣列中的下標

        TLE的原因應該是序列化的過程中,我的這種做法會記錄大量不存在的None節點,並且在反序列化的過程中,也要去考慮這些
        None的節點,導致整個樹的處理時間變長,用DFS的話,建立的序列會更短
        ps:如果可以建立兩個string的話,就可以記錄兩種序列,先序序列和中序序列,然後就可以按照先序序列和中序序列來構造二叉樹了
    """

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

        :type root: TreeNode
        :rtype: str
        """
        if root == None:
            return ''
        nodes = ['None']
        queue = [(root, 1)]
        while queue:
            node, index = queue.pop(0)
            while index >= len(nodes):
                nodes.append('None')
            nodes[index] = str(node.val)
            # nodes.extend(['None','None'])
            if node.left:
                # nodes[2*index-1] = str(node.left.val)
                queue.append((node.left, 2 * index))
            if node.right:
                # nodes[2*index] = str(node.right.val)
                queue.append((node.right, 2 * index + 1))

        return ','.join(nodes[1:])

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

        :type data: str
        :rtype: TreeNode
        """
        if data == '':
            return None
        data = data.split(',')
        TreeNodes = [None]
        for i in range(len(data)):
            if data[i] != 'None':
                TreeNodes.append(TreeNode(int(data[i])))
            else:
                TreeNodes.append(None)
        for i in range(1, len(TreeNodes)):
            if TreeNodes[i] != None:
                if 2 * i <= len(TreeNodes) - 1:
                    TreeNodes[i].left = TreeNodes[2 * i]
                if 2 * i + 1 <= len(TreeNodes) - 1:
                    TreeNodes[i].right = TreeNodes[2 * i + 1]
        return TreeNodes[1]