Skip to content

Latest commit

 

History

History

297

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

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.

Related Topics:
Tree, Design

Similar Questions:

Solution 1.

The tree [1,2,3,null,null,4,5] will be serialized to 1,2,3,#,#,4,5,#,#,#,#.

// OJ: https://leetcode.com/problems/serialize-and-deserialize-binary-tree/
// Author: github.com/lzl124631x
class Codec {
private:
    TreeNode *getNode(vector<string> &v, int &i) {
        string s = v[i++];
        return s == "#" ? NULL : new TreeNode(stoi(s));
    }
public:
    string serialize(TreeNode* root) {
        if (!root) return "";
        queue<TreeNode*> q;
        q.push(root);
        string ans;
        while (!q.empty()) {
            root = q.front();
            q.pop();
            if (!ans.empty()) ans += ',';
            if (root) {
                ans += to_string(root->val);
                q.push(root->left);
                q.push(root->right);
            } else ans += '#';
        }
        return ans;
    }
    TreeNode* deserialize(string data) {
        if (data.empty()) return NULL;
        stringstream ss(data);
        string val;
        vector<string> v;
        while (getline(ss, val, ',')) v.push_back(val);
        TreeNode *root = new TreeNode(stoi(v[0]));
        queue<TreeNode*> q;
        q.push(root);
        int i = 1;
        while (i < v.size()) {
            TreeNode *node = q.front();
            q.pop();
            node->left = getNode(v, i);
            node->right = getNode(v, i);
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
        return root;
    }
};

Solution 2.

Same as how LeetCode do it.

// OJ: https://leetcode.com/problems/serialize-and-deserialize-binary-tree/
// Author: github.com/lzl124631x
vector<string> stringToVector(string str) {
	str = str.substr(1, str.size() - 2);
	istringstream ss(str);
	string token;
	vector<string> ans;
	while (getline(ss, token, ',')) ans.push_back(token);
	return ans;
}

string vectorToString(vector<string> v){
	auto i = v.begin();
	ostringstream ans;
    ans << "[";
	for(; i != v.end(); ++i) {
		ans << *i;
		if (i + 1 != v.end()) ans << ",";
	}
	ans << "]";
	return ans.str();
}

class Codec {
private:
    string nilToken = "null";
public:
    TreeNode* deserialize(string str) {
        auto v = stringToVector(str);
        if (v.empty()) return NULL;
        queue<TreeNode*> q;
        auto root = new TreeNode(stoi(v[0]));
        q.push(root);
        for (int i = 1, N = v.size(); i < N;) {
            auto node = q.front();
            q.pop();
            if (v[i] != nilToken) q.push(node->left = new TreeNode(stoi(v[i])));
            ++i;
            if (i < N && v[i] != nilToken) q.push(node->right = new TreeNode(stoi(v[i])));
            ++i;
        }
        return root;
    }

    string serialize(TreeNode* root) {
        vector<string> v;
        if (!root) return vectorToString(v);
        queue<TreeNode*> q;
        q.push(root);
        while (q.size()) {
            root = q.front();
            q.pop();
            if (root) {
                v.push_back(to_string(root->val));
                q.push(root->left);
                q.push(root->right);
            } else v.push_back(nilToken);
            
        }
        while (v.back() == nilToken) v.pop_back();
        return vectorToString(v);
    }
};

Solution 3.

// OJ: https://leetcode.com/problems/serialize-and-deserialize-binary-tree/
// Author: github.com/lzl124631x
class Codec {
public:
    string serialize(TreeNode* root) {
        if (!root) return "[]";
        vector<TreeNode*> v;
        queue<TreeNode*> q;
        q.push(root);
        while (q.size()) {
            root = q.front();
            q.pop();
            v.push_back(root);
            if (root) {
                q.push(root->left);
                q.push(root->right);
            }
        }
        while (v.back() == NULL) v.pop_back();
        string ans = "[";
        for (int i = 0; i < v.size(); ++i) {
            ans += v[i] ? to_string(v[i]->val) : "null";
            ans += i == v.size() - 1 ? "]" : ",";
        }
        return ans;
    }

    TreeNode* deserialize(string data) {
        vector<TreeNode*> v;
        int i = 1, N = data.size() - 1;
        while (i < N) {
            TreeNode *node = NULL;
            if (data[i] == 'n') i += 4;
            else {
                long n = 0, sign = 1;
                if (data[i] == '-') {
                    sign = -1;
                    ++i;
                }
                while (i < N && isdigit(data[i])) n = n * 10 + (data[i++] - '0');
                node = new TreeNode(sign * n);
            }
            ++i;
            v.push_back(node);
        }
        TreeNode *root;
        queue<TreeNode**> q;
        q.push(&root);
        for (auto node : v) {
            auto p = q.front();
            q.pop();
            *p = node;
            if (node) {
                q.push(&node->left);
                q.push(&node->right);
            }
        }
        return root;
    }
};

Solution 4.

// OJ: https://leetcode.com/problems/serialize-and-deserialize-binary-tree/
// Author: github.com/lzl124631x
// Ref: https://leetcode.com/problems/serialize-and-deserialize-binary-tree/discuss/74259/Recursive-preorder-Python-and-C%2B%2B-O(n)
class Codec {
    void serialize(TreeNode *root, ostringstream &out) {
        if (root) {
            out << root->val << ' ';
            serialize(root->left, out);
            serialize(root->right, out);
        } else out << "# ";
    }
    TreeNode *deserialize(istringstream &in) {
        string val;
        in >> val;
        if (val == "#") return NULL;
        auto root = new TreeNode(stoi(val));
        root->left = deserialize(in);
        root->right = deserialize(in);
        return root;
    }
public:
    string serialize(TreeNode* root) {
        ostringstream out;
        serialize(root, out);
        return out.str();
    }
    TreeNode* deserialize(string data) {
        istringstream in(data);
        return deserialize(in);
    }
};