LeetCodee

297. Serialize and Deserialize Binary Tree

Jump to Solution: Python Java C++ JavaScript C#

Problem Description

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.

Clarification: The input/output 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.

Example 1:

Input: root = [1,2,3,null,null,4,5]
Output: [1,2,3,null,null,4,5]

Example 2:

Input: root = []
Output: []

Constraints:

  • The number of nodes in the tree is in the range [0, 10⁴]
  • -1000 <= Node.val <= 1000

Solution

Python Solution

# 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
        """
        if not root:
            return "null"
        return str(root.val) + "," + self.serialize(root.left) + "," + self.serialize(root.right)

    def deserialize(self, data):
        """Decodes your encoded data to tree.
        :type data: str
        :rtype: TreeNode
        """
        def dfs():
            val = next(values)
            if val == "null":
                return None
            node = TreeNode(int(val))
            node.left = dfs()
            node.right = dfs()
            return node
            
        values = iter(data.split(","))
        return dfs()

Time Complexity: O(n)

Need to visit each node once for both serialization and deserialization.

Space Complexity: O(n)

Need to store the string representation of the tree.

Java Solution

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Codec {
    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if (root == null) {
            return "null";
        }
        return root.val + "," + serialize(root.left) + "," + serialize(root.right);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        Queue queue = new LinkedList<>(Arrays.asList(data.split(",")));
        return deserializeHelper(queue);
    }
    
    private TreeNode deserializeHelper(Queue queue) {
        String val = queue.poll();
        if (val.equals("null")) {
            return null;
        }
        TreeNode node = new TreeNode(Integer.parseInt(val));
        node.left = deserializeHelper(queue);
        node.right = deserializeHelper(queue);
        return node;
    }
}

Time Complexity: O(n)

Need to visit each node once for both serialization and deserialization.

Space Complexity: O(n)

Need to store the string representation of the tree.

C++ Solution

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:
    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if (!root) {
            return "null";
        }
        return to_string(root->val) + "," + serialize(root->left) + "," + serialize(root->right);
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        stringstream ss(data);
        string item;
        queue q;
        while (getline(ss, item, ',')) {
            q.push(item);
        }
        return deserializeHelper(q);
    }
    
private:
    TreeNode* deserializeHelper(queue& q) {
        string val = q.front();
        q.pop();
        if (val == "null") {
            return nullptr;
        }
        TreeNode* node = new TreeNode(stoi(val));
        node->left = deserializeHelper(q);
        node->right = deserializeHelper(q);
        return node;
    }
};

Time Complexity: O(n)

Need to visit each node once for both serialization and deserialization.

Space Complexity: O(n)

Need to store the string representation of the tree.

JavaScript Solution

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */

/**
 * Encodes a tree to a single string.
 *
 * @param {TreeNode} root
 * @return {string}
 */
var serialize = function(root) {
    if (!root) {
        return "null";
    }
    return root.val + "," + serialize(root.left) + "," + serialize(root.right);
};

/**
 * Decodes your encoded data to tree.
 *
 * @param {string} data
 * @return {TreeNode}
 */
var deserialize = function(data) {
    const values = data.split(",");
    let index = 0;
    
    function dfs() {
        const val = values[index++];
        if (val === "null") {
            return null;
        }
        const node = new TreeNode(parseInt(val));
        node.left = dfs();
        node.right = dfs();
        return node;
    }
    
    return dfs();
};

Time Complexity: O(n)

Need to visit each node once for both serialization and deserialization.

Space Complexity: O(n)

Need to store the string representation of the tree.

C# Solution

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int x) { val = x; }
 * }
 */
public class Codec {
    // Encodes a tree to a single string.
    public string serialize(TreeNode root) {
        if (root == null) {
            return "null";
        }
        return root.val + "," + serialize(root.left) + "," + serialize(root.right);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(string data) {
        Queue queue = new Queue(data.Split(','));
        return deserializeHelper(queue);
    }
    
    private TreeNode deserializeHelper(Queue queue) {
        string val = queue.Dequeue();
        if (val == "null") {
            return null;
        }
        TreeNode node = new TreeNode(int.Parse(val));
        node.left = deserializeHelper(queue);
        node.right = deserializeHelper(queue);
        return node;
    }
}

Time Complexity: O(n)

Need to visit each node once for both serialization and deserialization.

Space Complexity: O(n)

Need to store the string representation of the tree.

Approach Explanation

The solution uses preorder traversal for serialization and deserialization:

  1. Key Insight:
    • Use preorder traversal (root, left, right)
    • Mark null nodes explicitly
    • Use comma as delimiter
    • Reconstruct using recursion
  2. Serialization Steps:
    • Handle null case
    • Convert root value to string
    • Recursively serialize left
    • Recursively serialize right

Example walkthrough:

  • Tree: [1,2,3,null,null,4,5]
  • Serialized: "1,2,null,null,3,4,null,null,5,null,null"
  • Deserialization rebuilds tree
  • Uses queue/iterator for values

Alternative approaches:

  • Level order traversal
  • JSON serialization
  • Binary serialization
  • Custom encoding schemes

Edge Cases:

  • Empty tree
  • Single node tree
  • Unbalanced tree
  • Full binary tree