题解 | #序列化二叉树#

序列化二叉树

https://www.nowcoder.com/practice/cf7e25aa97c04cc1a68c8f040e71fb84

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
#include <cstddef>
#include <cstring>
class Solution {
  public:
    char* Serialize(TreeNode* root) {
        if (root == nullptr) return "#";
        deque<TreeNode*> deq;
        deq.push_back(root);
        string res;
        int i = 1, num_count = 0, num_null_prev = 0, num_null_cur = 0;
        //层序遍历,数字之间使用!间隔,nullptr用#表示,先构建一个deque列表
        while (!deq.empty()) {
            TreeNode* temp = deq.front();
            deq.pop_front();
            if (temp != nullptr) {
                num_count++;
                res += to_string(temp->val) + "!";
                deq.push_back(temp->left);
                deq.push_back(temp->right);
            } else {
                num_null_cur++;
                res += '#';
            }
            //判断是第几层,该层是否已经满了。
            //i表示第i层,判断是否满足2^(i-1)=上一层nullptr的个数*2+当前层数字个数+当前层nullptr的个数,满足时当前层满了
		  //之前都没有空结点
            if (num_null_prev == 0) {
			  //当前层满了
                if (num_count + num_null_cur == pow(2, i - 1)) {
                    i++;
				  //到下一层的时候需要更新数值
                    num_count = 0;
                    num_null_prev = num_null_cur;
                    num_null_cur = 0;
                }
            } else {
			  //当前层满了
                if (2 * num_null_prev + num_null_cur + num_count == pow(2, i - 1)) {
                    i++;
                    num_count = 0;
				  //前一层空结点个数 = 前一层空结点个数*2+当前层空结点个数
                    num_null_prev = num_null_cur + 2 * num_null_prev;
                    num_null_cur = 0;
                }
            }
        }
        //最后的叶结点添加了2个nullptr进入deque中,多算了一层;在公式中又多加了一层,所以是减2
        i -= 2;
        //!的位置为终点的位置,计算长度(长度为终点位置+1),char*数组需在长度的基础上再+1,因为要加终止符
        int pos = res.find_last_of('!');
        char* res_ptr = new char[pos + 2];
        res = res.substr(0, pos + 1);

        strcpy(res_ptr, res.c_str());
        res_ptr[pos + 1] = '\0';
        return res_ptr;
    }
    TreeNode* Deserialize(char* str) {
        if (str == nullptr) return nullptr;
        deque<TreeNode*> deq1, deq2;
        string val;
        //构建两个队列,第一个队列为父结点,第二个队列为子节点,第二个队列删去根结点。
        for (int i = 0; str[i] != '\0'; i++) {
            if (isdigit(str[i])) {
                val += str[i];
            } else if (str[i] == '!') {
                TreeNode* temp = new TreeNode(atoi(val.c_str()));
                deq1.push_back(temp);
                deq2.push_back(temp);
                val.clear();
            } else {
                deq1.push_back(nullptr);
                deq2.push_back(nullptr);
            }
        }
        deq2.pop_front();
        TreeNode* root = deq1.front(), *cur = root;

        //当取出一个非空父结点时,对应取出两个子节点;空的父结点跳过。当子节点的deque为空时,结束循环
        while (deq2.size() != 0) {
            cur = deq1.front();
            deq1.pop_front();
            if (cur != nullptr) {
                //判断子节点列表是否为空,空则跳出循环
                if (deq2.size() == 0) break;
                cur->left = deq2.front();
                deq2.pop_front();
                
                //判断子节点列表是否为空,空则跳出循环
                if (deq2.size() == 0) break;
                cur->right = deq2.front();
                deq2.pop_front();
            }
        }
        return root;
    }
};

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务