Saturday, August 26, 2017

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.
For example, you may serialize the following tree
    1
   / \
  2   3
     / \
    4   5
as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ 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.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:
    vector<string> split(string s) {
        vector<string> split_str;
        stringstream ss(s);
        string tmp;
        while (getline(ss, tmp, ',')) {
            split_str.push_back(tmp);
        }
        return split_str;
    }

    // Encodes a tree to a single string.
    vector<string> serialize(TreeNode* root) {
        vector<string> serialized;
        string ans;
        if (root == NULL) {
            return serialized;
        }
        queue<TreeNode *> q;
        q.push(root);
        while (!q.empty()) {
            TreeNode *node = q.front(); q.pop();
            if (ans.empty()) {
                ans = to_string(node -> val);
            } else {
                ans += "," + (node != NULL ? to_string(node -> val) : "#");
            }
            if (node != NULL) {
                q.push(node -> left);
                q.push(node -> right);
            }
        }
        
        serialized = split(ans);
        int size = serialized.size() - 1;
        while (size >= 0) {
            if (serialized[size--] != "#") {
                break;
            }
            serialized.erase(serialized.begin() + size + 1);
        }
        return serialized; 
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(vector<string> data) {
        if (data.empty()) {
            return NULL;
        }
        TreeNode *root = new TreeNode(stoi(data[0]));
        int size = data.size(), i = 1;
        queue<TreeNode *> q;
        q.push(root);
        
        while (i < size && !q.empty()) {
            TreeNode *node = q.front(); q.pop();
            if (data[i++] != "#") {
                node -> left = new TreeNode(stoi(data[i - 1]));
                q.push(node -> left);
            }
            if (data[i++] != "#") {
                node -> right = new TreeNode(stoi(data[i - 1]));
                q.push(node -> right);
            }
        }
        return root;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));


========== Another =========
/**
 * 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) {
        string ans;
        if (root == NULL) {
            return ans;
        }
        vector<string> sol;
        queue<TreeNode *> q;
        q.push(root);
        while (!q.empty()) {
            TreeNode *node = q.front(); q.pop();
            if (node != NULL) {
                sol.push_back(to_string(node -> val));
                q.push(node -> left);
                q.push(node -> right);
            } else {
                sol.push_back("null");
            }
        }
        
        formatResponse(ans, sol);
        return ans;
    }
    
    void formatResponse(string& ans, vector<string>& strList) {
        int size = strList.size();
        if (size == 0) {
            ans = "";
            return;
        }
        
        for (int i = size - 1; i >= 0; i--) {
            if (strList[i] == "null") {
                strList.pop_back();
            } else {
                break;
            }
        }
        
        for (int i = 0; i < strList.size(); i++) {
            if (i == 0) {
                ans += strList[i];
            } else {
                ans += "," + strList[i];
            }
        }
    }

    void split(string s, vector<string>& resp, char delim) {
        stringstream ss(s);
        string str;
        while(getline(ss, str, delim)) {
            resp.push_back(str);
        }
        return;
    }
    
    void helper(TreeNode *& root, vector<string>& input) {
        if (input.size() == 0 || input[0] == "null") {
            root = NULL;
            return;
        }
        
        root = new TreeNode(stoi(input[0]));
        queue<TreeNode *> q;
        q.push(root);
        int size = input.size();
        int iter = 1;
        while (1) {
            if (q.empty() || iter == size) {
                break;
            }
            TreeNode *node = q.front(); q.pop();
            if (input[iter] != "null") {
                node -> left = new TreeNode(stoi(input[iter]));
                q.push(node -> left);
            } else {
                node -> left = NULL;
            }
            iter++;
            if (iter == size) {
                break;
            }
            if (input[iter] != "null") {
                node -> right = new TreeNode(stoi(input[iter]));
                q.push(node -> right);
            } else {
                node -> right = NULL;
            }
            iter++;
        }
    }
    
    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        TreeNode *root = NULL;
        if (data.empty()) {
            return root;
        }
        
        vector<string> input;
        split(data, input, ',');
        
        helper(root, input);
        return root;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;

// codec.deserialize(codec.serialize(root));

========================
/**
 * 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:
    vector<string> split(string str) {
        stringstream ss(str);
        vector<string> ans;
        string tmp;
        while(getline(ss, tmp, ',')) {
            ans.push_back(tmp);
        }
        return ans;
    }

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        queue<TreeNode *> q;
        if (root == NULL) {
            return "";
        }
        string ans;
        q.push(root);
        while (!q.empty()) {
            TreeNode *node = q.front(); q.pop();
            string code;
            if (node != NULL) {
                code = to_string(node -> val);
            } else {
                code = "#";
            }
            ans += (ans != "" ? "," +  code: code);
            if (node == NULL) {
                continue;
            }
            q.push(node -> left);
            q.push(node -> right);
        }
        // Check if trimming needed in the last.
        return ans;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if (data == "" || data == "#") {
            return NULL;
        }
        
        vector<string> str_list = split(data);
        queue<TreeNode *> q;
        TreeNode *root = new TreeNode(stoi(str_list[0]));
        q.push(root);
        int iter = 1;
        while (iter == 0 || !q.empty()) {
            TreeNode *node = q.front(); q.pop();
            string val = str_list[iter];
            if (val != "#") {
                node -> left = new TreeNode(stoi(val));
                q.push(node -> left);
            }
            iter++;
            if (iter == str_list.size()) {
                return root;
            }
            val = str_list[iter];
            if (val != "#") {
                node -> right = new TreeNode(stoi(val));
                q.push(node -> right);
            }
            iter++;
            if (iter == str_list.size()) {
                return root;
            }
        }
        return root;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

No comments:

Post a Comment