首页 > 其他分享 >剑指 Offer 37. 序列化二叉树

剑指 Offer 37. 序列化二叉树

时间:2023-04-08 23:44:09浏览次数:56  
标签:right TreeNode string data 37 二叉树 序列化 root left

题目链接:剑指 Offer 37. 序列化二叉树

取巧做法

class Codec {
private:
    TreeNode* root;
public:
    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        this->root = root;
        return "";
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        return this->root;
    }
};

方法一:后序遍历实现

解题思路

将树后续遍历为字符串保存,并记录每个节点的左右子树的节点个数,然后取序列最后一个数为根节点,通过其左右子树的节点个数,递归的\(build\)其左右子树。

代码

class Codec {
private:
    vector<vector<int>> childNum; // 用于对后序遍历序列进行反序列化过程中判断当前根节点的左右子树集合
public:
    string postorder(TreeNode* root, int &leftNum, int &rightNum) {
        string left, right;
        int child_1_left_num = 0, child_1_right_num = 0;
        int child_2_left_num = 0, child_2_right_num = 0;
        if (root->left) {
            left = postorder(root->left, child_1_left_num, child_1_right_num);
            leftNum ++ ;
        }
        if (root->right) {
            right = postorder(root->right, child_2_left_num, child_2_right_num);
            rightNum ++ ;
        }
        leftNum += child_1_left_num + child_1_right_num;
        rightNum += child_2_left_num + child_2_right_num;
        childNum.push_back({leftNum, rightNum});
        if (left.length() != 0) left += ",";
        if (right.length() != 0) right += ",";
        return left + right + to_string(root->val);
    }

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if (!root) return "";
        int leftNum = 0, rightNum = 0;
        return postorder(root, leftNum, rightNum);
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if (data.length() == 0) return NULL;
        int n = data.size();
        vector<int> value;
        for (int i = 0, j = 0; i < n; i = j + 1, j = i ) { // string转换为数组
            while (j < n) {
                if (data[j] == ',') break;
                j ++ ;
            }
            value.push_back(stoi(data.substr(i, j - i)));
        }
        // build tree
        function<TreeNode*(int, int)> build = [&](int l, int r) -> TreeNode* {
            if (l > r) return NULL;
            int mid = l + childNum[r][0] - 1;
            TreeNode* root = new TreeNode(value[r]);
            root->left = build(l, mid);
            root->right = build(mid + 1, r - 1);
            return root;
        };
        return build(0, value.size() - 1);
    }
};

复杂度分析

时间复杂度:\(O(n)\),\(n\)为节点个数;
空间复杂度:\(O(n)\),递归栈空间 和 \(childNum\)数组。

方法二:层序遍历实现

解题思路

先对树进行层序遍历,在遍历的过程中,叶子节点的左右空节点也加入序列中;然后在进行层序遍历构造树,维护一个指针\(i\),指向当前节点的孩子节点。

代码

class Codec {
public:
    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if (!root) return "";
        string str;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            TreeNode* front = q.front();
            q.pop();
            if (str.length() != 0) str += ",";
            if (!front) str += "#";
            else {
                str += to_string(front->val);
                q.push(front->left);
                q.push(front->right);
            }
        }
        return str;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if (data.length() == 0) return NULL;
        int i = 0, idx = data.find_first_of(",", i);
        TreeNode* root = new TreeNode(stoi(data.substr(i, idx - i)));
        i = idx + 1 ;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            TreeNode* front = q.front();
            q.pop();
            idx = data.find_first_of(",", i);
            front->left = data.substr(i, idx - i) == "#" ? NULL : new TreeNode(stoi(data.substr(i, idx - i)));
            i = idx + 1;
            idx = data.find_first_of(",", i);
            front->right = data.substr(i, idx - i) == "#" ? NULL : new TreeNode(stoi(data.substr(i, idx - i)));
            i = idx + 1;
            if (front->left != NULL) q.push(front->left);
            if (front->right != NULL) q.push(front->right);
        }
        return root;
    }
};

复杂度分析

时间复杂度:\(O(n)\),\(n\)为节点个数;
空间复杂度:\(O(n)\),队列空间。

标签:right,TreeNode,string,data,37,二叉树,序列化,root,left
From: https://www.cnblogs.com/lxycoding/p/17299598.html

相关文章

  • 2379. 得到 K 个黑块的最少涂色次数
    题目链接:2379.得到K个黑块的最少涂色次数方法一:前缀和解题思路通过前缀和计算任意子区间\([i,i+k-1]\)中字母\(W\)的数量,\(ans=min([i,i+k-1].count('W'),i=0,1,...)。\)代码classSolution{public:intminimumRecolors(stringblocks,intk......
  • 自定义序列化器类
    @Serialization是一个自定义装饰器,通常用于序列化Python对象。使用@Serialization装饰器可以将一个类转换为可序列化的对象,这样就可以将其存储到文件或通过网络传输。下面是一个使用@Serialization装饰器的示例:importjsondefSerialization(cls):defserializ......
  • INM379计算机游戏结构
    INM379ComputerGamesArchitecture:CourseworkSpecificationSynopsisTheaimofthecourseworkistogiveyouexperienceofusingadeployment-readyproductionframeworktoproduceafullyfunctionalgamedemonstratingsoundarchitecturalprinciplesins......
  • JZ8 二叉树的下一个结点
    做法一:直接求出中序遍历,并用vector容器存储。/*structTreeLinkNode{intval;structTreeLinkNode*left;structTreeLinkNode*right;structTreeLinkNode*next;TreeLinkNode(intx):val(x),left(NULL),right(NULL),next(NULL){......
  • 1237. 找出给定方程的正整数解
    题目链接:1237.找出给定方程的正整数解方法一:二分查找解题思路枚举\(x\),然后对\(y\)进行二分查找,确定满足\(customfunction.f(x,y)==z\)的数对\((x,y)\),将其加入\(ans\)中,最终返回\(ans\)。代码/**//Thisisthecustomfunctioninterface.*//Youshou......
  • 617. 合并二叉树
    给你两棵二叉树:root1和root2。想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为null的节点将直接作为新二叉树......
  • 837. 连通块中点的数量
    linkcode#include<bits/stdc++.h>usingnamespacestd;constintN=100010;intfa[N],a[N];intcnt[N];intfind(intx){ if(x!=fa[x])fa[x]=find(fa[x]); returnfa[x];}voidun(intx,inty){ x=find(x); y=find(y); if(x!=y){ fa......
  • 106. 从中序与后序遍历序列构造二叉树 105. 从前序与中序遍历序列构造二叉树
    给定两个整数数组inorder和postorder,其中inorder是二叉树的中序遍历,postorder是同一棵树的后序遍历,请你构造并返回这颗二叉树。classSolution{public:TreeNode*buildTree(vector<int>&inorder,vector<int>&postorder){if(postorder.size()==0)......
  • 安装wsl的必备操作——开启CPU虚拟化——WslRegisterDistribution failed with error_
    参考:https://www.cnblogs.com/smdtxz/p/16837946.htmlhttps://www.cnblogs.com/wenonly/p/17206040.htmlhttps://blog.csdn.net/qq_41460654/article/details/118026986  ======================================================  因为实验室需要炼丹,而炼丹要用ubun......
  • 记spring-security升级,引发的redis反序列化不一致问题
    问题解决参考文章如下:https://my.oschina.net/klblog/blog/5559133https://blog.csdn.net/qq_37421368/article/details/124850449问题复现由于一些原因,登录的token由旧版本的微服务存入的redis,另一个新版本的微服务需要取出数据校验springboot版本升级导致spring-secu......