[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 题目讲解汇总(持续更新中...)

相关文章
相关标签/搜索