Serialize and Deserialize Binary Tree
Clarify the problem
The problem requires implementing two functions: serialize
and deserialize
. The serialize
function takes a binary tree as input and returns a string representation of the tree. The deserialize
function takes a string representation of a binary tree and reconstructs the original binary tree. We need to solve this problem without using any import or predefined functions.
Analyze the problem
To solve this problem, we need to convert the binary tree into a string representation such that we can reconstruct the original tree using the string. The string representation should preserve the tree's structure and allow us to differentiate between null nodes and non-null nodes.
Design an algorithm
To serialize the binary tree, we can perform a pre-order traversal of the tree. We'll append the node values to the serialized string, separating them by a delimiter. For null nodes, we'll use a special character to represent them. To deserialize the string, we'll split it by the delimiter and use a recursive approach to reconstruct the binary tree.
Explain your approach
We'll use a recursive approach for both serialization and deserialization. During serialization, we'll traverse the binary tree in pre-order and append the node values to a string, separating them by a delimiter. For null nodes, we'll use a special character (e.g., '#'). During deserialization, we'll split the string by the delimiter and use the pre-order traversal to construct the binary tree recursively.
Write clean and readable code
Here's an example implementation in Python:
python
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Codec:
def serialize(self, root):
def serializeHelper(node):
if node is None:
return '#'
return str(node.val) + ',' + serializeHelper(node.left) + ',' + serializeHelper(node.right)
return serializeHelper(root)
def deserialize(self, data):
def deserializeHelper(nodes):
val = nodes.pop(0)
if val == '#':
return None
node = TreeNode(int(val))
node.left = deserializeHelper(nodes)
node.right = deserializeHelper(nodes)
return node
nodes = data.split(',')
return deserializeHelper(nodes)
Test your code
To test the code, we can create a binary tree, serialize it, and then deserialize the serialized string to check if we get the original tree back. We should also test edge cases such as empty trees and trees with only one node.
python
# Create a binary tree
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.right.left = TreeNode(4)
root.right.right = TreeNode(5)
# Initialize the codec
codec = Codec()
# Test serialization and deserialization
serialized_tree = codec.serialize(root)
print("Serialized tree:", serialized_tree)
deserialized_tree = codec.deserialize(serialized_tree)
print("Deserialized tree:", deserialized_tree)
Optimize if necessary
The provided implementation already has a time complexity of O(N), where N is the number of nodes in the binary tree, as we perform a pre-order traversal. This solution is optimal in terms of time complexity.
Handle error cases
The provided implementation handles null nodes by using a special character ('#') to represent them during serialization. During deserialization, the code handles the special character appropriately to reconstruct the binary tree.
Discuss complexity analysis
The time complexity of the solution is O(N) for both serialization and deserialization, where N is the number of nodes in the binary tree. This is because we visit each node exactly once during the pre-order traversal. The space complexity is O(N) as well, considering the recursive call stack during deserialization.