297 Serialize and Deserialize Binary Tree

BFS

這題主要是要考資料結構的serialization

  • idea:

    • serialize: bfs visit all nodex, and concate to a string. use node_count to count total number of non null nodes
    • deserialize: read data and split by ',' create the first node and put it into queue read other nodes, link them to their parents in order, then put into queue too while loop ends when idx > splitData.length
  • code:

/**
 * 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) {
        /*
        bfs visit all nodes.
        and concate to a string
        */
        String s = "";
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int count_node = 1;
        while(!queue.isEmpty() && count_node > 0){
            TreeNode cur = queue.poll();
            if(cur!=null){
                s += cur.val + ",";
                count_node--;
            }
            else    s += "null,";
            if(cur != null){
                if(cur.left != null){
                    queue.offer(cur.left);
                    count_node++;
                }
                else    queue.offer(null);

                if(cur.right != null){
                    queue.offer(cur.right);
                    count_node++;
                }
                else    queue.offer(null);
            }
        }

        return s.substring(0,s.length()-1);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        /*
            read data and split by ','
            create the first node and put it into queue
            read other nodes, link them to their parents in order, then put into queue too
        */
        //base check
        if(data.length()== 0 || data.equals("") || data.equals("null")){
            return null;
        }

        //split
        String[] splitData = data.split(",");
        TreeNode root = new TreeNode(Integer.parseInt(splitData[0]));
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int idx = 1;//for splitData count

        while(!queue.isEmpty() && idx < splitData.length){
            TreeNode cur = queue.poll();
            String leftidx = splitData[idx++];
            String rightidx = "";
            if(idx < splitData.length)
                rightidx = splitData[idx++];

            TreeNode left=null, right=null;
            if(!leftidx.equals("null") && !leftidx.equals("")){
                left = new TreeNode(Integer.parseInt(leftidx));
                cur.left = left;
                queue.offer(left);
            }
            if(!rightidx.equals("null") && !rightidx.equals("")){
                right = new TreeNode(Integer.parseInt(rightidx));
                cur.right = right;
                queue.offer(right);
            }
        }

        return root;
    }
}

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

這個做法速度頗慢,雖然能AC,但只贏過2%

Recursive

我們也可以不要用BFS的作法,直接用recursive的解法,只是要先把serialize跟deserialize的順序想好,再來實作程式碼。

class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if (root == NULL) return "#";
        return to_string(root->val) + "," + serialize(root->left) + "," + serialize(root->right);
    }

    TreeNode* deserialize(string data) {
        if (data == "#") return NULL;
        stringstream s(data);
        return makeDeserialize(s);
    }

    TreeNode* makeDeserialize(stringstream& s) {
        string str;
        getline(s, str, ',');
        if (str == "#") {
            return NULL;
        } else {
            TreeNode* root = new TreeNode(stoi(str));
            root->left = makeDeserialize(s);
            root->right = makeDeserialize(s);
            return root;
        }
    }
};

其中stringstream的部分在使用getline之後,會自動把已經取出的部分砍掉。寫一小段程式碼來驗證這個行為:

#include <iostream>
#include <sstream>
using namespace std;

int main() {
    // your code goes here
    stringstream ss("1,2,3,4,5,6");

    string str;

    getline(ss, str, ',');
    cout << str << endl;

    getline(ss, str, ',');
    cout << str << endl;

    return 0;
}

以上這段程式碼執行的結果就是:

1
2

results matching ""

    No results matching ""