[LeetCode] Serialize and Deserialize N-ary Tree N叉搜索樹的序列化和去序列化

 

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.css

Design an algorithm to serialize and deserialize an N-ary tree. An N-ary tree is a rooted tree in which each node has no more than N children. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that an N-ary tree can be serialized to a string and this string can be deserialized to the original tree structure.html

For example, you may serialize the following 3-ary treenode

 

 

as [1 [3[5 6] 2 4]]. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.數組

 

Note:網絡

  1. N is in the range of [1, 1000]
  2. Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
 

這道題讓咱們對N叉樹進行序列化和去序列化,序列化就是將一個數據結構或物體轉化爲一個位序列,能夠存進一個文件或者內存緩衝器中,而後經過網絡鏈接在相同的或者另外一個電腦環境中被還原,還原的過程叫作去序列化。如今讓咱們來序列化和去序列化一個二叉樹,並給了咱們例子。因爲咱們有了以前那道Serialize and Deserialize Binary Tree對二叉樹的序列化和去序列化的基礎,那麼這道N叉樹的方法也是大同小異了。首先使用先序遍歷的遞歸解法,遞歸的寫法就十分的簡潔了,對於序列化,咱們須要一個helper函數,裏面首先判斷結點,若爲空,則結果res加上一個井字符,不然加上當前結點值,跟一個空格,再加上子結點的個數值,再跟一個空格。以後就是遍歷子結點了,對每一個子結點都調用遞歸函數便可。去序列函數須要用一個字符串流類來幫助讀字符,這個類是按空格來斷開字符串的,因此咱們在序列化的時候中間都是用的空格。咱們一樣須要一個helper函數,首先讀出結點值,若是讀出了井字號,直接返回空。不然繼續讀出子結點的個數,有告終點值咱們就能夠新建一個結點了,同時知道了子結點的個數,那麼咱們就循環調用遞歸函數相同的次數,將返回的子結點加入子結點數組便可,參見代碼以下:數據結構

 

解法一:app

class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(Node* root) {
        string res;
        serializeHelper(root, res);
        return res;
    }
    
    void serializeHelper(Node* node, string& res) {
        if (!node) res += "#";
        else {
            res += to_string(node->val) + " " + to_string(node->children.size()) + " ";
            for (auto child : node->children) {
                serializeHelper(child, res);
            }
        }
    }

    // Decodes your encoded data to tree.
    Node* deserialize(string data) {
        istringstream iss(data);
        return deserializeHelper(iss);
    }
    
    Node* deserializeHelper(istringstream& iss) {
        string val = "", size = "";
        iss >> val;
        if (val == "#") return NULL;
        iss >> size;
        Node *node = new Node(stoi(val), {});
        for (int i = 0; i < stoi(size); ++i) {
            node->children.push_back(deserializeHelper(iss));
        }
        return node;
    }
};

 

咱們還可使用層序遍歷的迭代寫法,序列化的函數相對來講好一點,仍是先判空,若爲空,直接返回井字號。不然就使用隊列,加入根結點,而後就進行while循環,先取出隊首結點,而後res加入結點值,再加入空格,加入子結點個數,再加上空格。以後再把每個子結點都加入隊列中便可。去序列化函數稍稍複雜一些,仍是要用字符流類來讀取字符,須要用兩個隊列,分別來保存結點,和子結點個數。首先咱們先取出結點值,若是是井字號,直接返回空。不然再取出子結點個數,咱們先根據以前取出的結點值新建一個結點,而後加入結點隊列,把子結點個數加入個數隊列。而後就開始遍歷了,首先分別取出結點隊列和個數隊列的隊首元素,而後循環子結點個數次,再取出結點值,和子結點個數,若是其中某個值沒取出來,就break掉。根據取出的結點值新建一個結點,而後將結點值加入結點隊列,子結點個數加入個數隊列,而後將子結點加入子結點數組,參見代碼以下:less

 

解法二:函數

class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(Node* root) {
        if (!root) return "#";
        string res;
        queue<Node*> q{{root}};
        while (!q.empty()) {
            Node *t = q.front(); q.pop();
            res += to_string(t->val) + " " + to_string(t->children.size()) + " ";
            for (Node *child : t->children) {
                q.push(child);
            }
        }
        return res;
    }

    // Decodes your encoded data to tree.
    Node* deserialize(string data) {
        istringstream iss(data);
        queue<Node*> qNode;
        queue<int> qSize;
        string val = "", size = "";
        iss >> val;
        if (val == "#") return NULL;
        iss >> size;
        Node *res = new Node(stoi(val), {}), *cur = res;
        qNode.push(cur);
        qSize.push(stoi(size));
        while (!qNode.empty()) {
            Node *t = qNode.front(); qNode.pop();
            int len = qSize.front(); qSize.pop();
            for (int i = 0; i < len; ++i) {
                if (!(iss >> val)) break;
                if (!(iss >> size)) break;
                cur = new Node(stoi(val), {});
                qNode.push(cur);
                qSize.push(stoi(size));
                t->children.push_back(cur);
            }
        }
        return res;
    }
};

 

相似題目:post

Serialize and Deserialize BST 

Serialize and Deserialize Binary Tree

Encode N-ary Tree to Binary Tree

 

參考資料:

https://leetcode.com/problems/serialize-and-deserialize-n-ary-tree

 

LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索