## 297. Serialize and Deserialize Binary Tree
#
# Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
#
# Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
#
# Example:
#     You may serialize the following tree:
#
#         1
#        / \
#       2   3
#          / \
#         4   5
#
#     as "[1,2,3,null,null,4,5]"
#
# Clarification: The above format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
#
# Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
##


# 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
        """
        results = []
        def strSerialize(node):
            if node:
                results.append(str(node.val))
                strSerialize(node.left)
                strSerialize(node.right)
            else:
                results.append("None")
        strSerialize(root)
        resultStr = " ".join(results)
        # print(resultStr)
        return resultStr


    def deserialize(self, data):
        """Decodes your encoded data to tree.
        :type data: str
        :rtype: TreeNode
        """
        def strDeserialize(nodes):
            if nodes[0] == "None":
                nodes.pop(0)
                return None
            root = TreeNode(nodes[0])
            nodes.pop(0)
            root.left = strDeserialize(nodes)
            root.right = strDeserialize(nodes)
            return root
        temp = data.split()
        root = strDeserialize(temp)
        # print(root.val)
        return root


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

root = TreeNode(1)
l1 = TreeNode(2)
r1 = TreeNode(3)
r1l2 = TreeNode(4)
r1r2 = TreeNode(5)
root.left = l1
root.right = r1
r1.left = r1l2
r1.right = r1l2

codec.deserialize(codec.serialize(root))