【LeetCode - 每日一题】449. 序列化和反序列化二叉搜索树(23.09.04)

这篇具有很好参考价值的文章主要介绍了【LeetCode - 每日一题】449. 序列化和反序列化二叉搜索树(23.09.04)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

449. 序列化和反序列化二叉搜索树

题意

  • 给定一棵二叉搜索树,实现序列化和反序列化;
  • 注意 val 范围,因此 在序列化时需要插入分隔符分割每个节点的 val
  • 要善于利用 二叉搜索树的特性(中序遍历 = 递增排序)

解法

  • 前序遍历 + 中序遍历 可以重构一棵树,又由于二叉搜索树自带中序遍历,因此在序列化时保存前序遍历;
  • 由于节点的 val 不一定是个位数,所以要在序列化时插入分隔符;
  • 在反序列化时,首先分割字符串,得到前序遍历,然后通过前序遍历和中序遍历进行二叉搜索树的重构。
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:
    void PreOrder(TreeNode* root, string& data)
    {
        if(root == nullptr) return;

        data.append(to_string(root->val) + ","); 	// , 作为分隔符

        // if(root->left != nullptr) 	递归函数开头就判断了非空的情况,因此这里不需要再次判断了
        PreOrder(root->left, data);
        // if(root->right != nullptr) 	递归函数开头就判断了非空的情况,因此这里不需要再次判断了
        PreOrder(root->right, data);
    }

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string res = "";

        PreOrder(root, res);

        return res;
    }

    vector<int> Split(string data) 	// 将序列化后的 string 进行分割,得到每个节点的 val
    {
        int idx = 0;
        int curS = 0;
        vector<int> ans;

        while(idx < data.size())
        {
            if(data[idx] == ',')
            {
                string cur = data.substr(curS, idx - curS);
                ans.emplace_back(stoi(cur));
                curS = idx + 1;
            }
            idx++;
        }
        return ans;
    }
    TreeNode* ReconstructTree(vector<int> data, int s, int t)
    {
        TreeNode* root = new TreeNode(data[s]);
        int rightIdx = -1;

        // 没有孩子
        if(s == t)
            return root;

        // 寻找右孩子的根
        for(int i = s + 1; i <= t; i++)
        {
            if(data[i] > root->val)
            {
                rightIdx = i;
                break;
            }
        }

        if(rightIdx == -1)  // 没有右孩子
        {
            root->right = nullptr;

            // 构建左孩子
            root->left = ReconstructTree(data, s + 1, t);
        }
        else if(rightIdx == s + 1)  // 没有左孩子
        {
            root->left = nullptr;
            // 构建右孩子
            root->right = ReconstructTree(data, s + 1, t);
        }
        else
        {
            // 有左孩子,构建左孩子和右孩子
            root->left = ReconstructTree(data, s + 1, rightIdx - 1);
            root->right = ReconstructTree(data, rightIdx, t);
        }

        return root;
    }
    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if(data == "") return nullptr;

        vector<int> intData = Split(data);

        TreeNode* root = ReconstructTree(intData, 0, intData.size()-1);

        return root;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec* ser = new Codec();
// Codec* deser = new Codec();
// string tree = ser->serialize(root);
// TreeNode* ans = deser->deserialize(tree);
// return ans;

复杂度

时间复杂度:O(N),序列化前序遍历每个节点,反序列化也是恢复每个节点;
空间复杂度:O(N),存储序列化后的字符串。文章来源地址https://www.toymoban.com/news/detail-694969.html


到了这里,关于【LeetCode - 每日一题】449. 序列化和反序列化二叉搜索树(23.09.04)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Leetcode 297. 二叉树的序列化与反序列化

    297. 二叉树的序列化与反序列化

    2024年02月07日
    浏览(31)
  • 【LeetCode力扣】297. 二叉树的序列化与反序列化

      目录 1、题目介绍 2、解题思路  2.1、详细过程图解 2.2、代码描述   2.3、完整代码   原题链接:297. 二叉树的序列化与反序列化 - 力扣(LeetCode)   示例 1: 输入: root = [1,2,3,null,null,4,5] 输出: [1,2,3,null,null,4,5] 示例 2: 输入: root = [ ] 输出: [ ] 示例 3: 输入: root = [1

    2024年02月08日
    浏览(35)
  • 什么是序列化和反序列化?

    JSON(JavaScript Object Notation)和XML(eXtensible Markup Language)是两种常用的数据交换格式,用于在不同系统之间传输和存储数据。 JSON是一种轻量级的数据交换格式,它使用易于理解的键值对的形式表示数据。JSON数据结构简单明了,易于读写和解析,是基于JavaScript的一种常用数据

    2024年02月09日
    浏览(43)
  • Java序列化和反序列化

    目录 一、序列化和反序列化 二、Java序列化演示 三、反序列化漏洞 1、含义 ​序列化就是内存中的对象写入到IO流中,保存的格式可以是二进制或者文本内容。反序列化就是IO流还原成对象。 2、用途 (1)传输网络对象 (2)保存Session 1、序列化 java.io.ObjectOutputStream代表对象

    2023年04月25日
    浏览(27)
  • Unity-序列化和反序列化

    序列化是指把对象转换为字节序列的过程,而反序列化是指把字节序列恢复为对象的过程。序列化最主要的用途就是传递对象和保存对象。 在Unity中保存和加载、prefab、scene、Inspector窗口、实例化预制体等都使用了序列化与反序列化。 1 自定义的具有Serializable特性的非抽象、

    2024年01月24日
    浏览(42)
  • 【Linux】序列化和反序列化

    在网络编程中,直接使用 结构体 进行数据传输会出错,因为 本质上socket无法传输结构体 ,我们只有将结构体装换为字节数组,或者是字符串格式来传输,然后对端主机收到了数据,再将其转化为结构体,这就是序列化和反序列化的过程! 序列化 (Serialization)是将对象的状态

    2024年02月10日
    浏览(30)
  • Java序列化和反序列化机制

    在阅读 ArrayList 源码的时候,注意到,其内部的成员变量动态数组 elementData 被Java中的 transient 修饰 transient 意味着Java在序列化时会跳过该字段(不序列化该字段) 而Java在默认情况下会序列化类(实现了 Java.io.Serializable 接口的类)的所有非瞬态(未被 transient 修饰

    2024年03月15日
    浏览(37)
  • [计算机网络]---序列化和反序列化

    前言 作者 :小蜗牛向前冲 名言 :我可以接受失败,但我不能接受放弃    如果觉的博主的文章还不错的话,还请 点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正  目录  一、再谈协议 二、序列化和反序化 1、网络版本计算器的场景搭建 2、

    2024年02月20日
    浏览(35)
  • TCP定制协议,序列化和反序列化

    目录 前言 1.理解协议 2.网络版本计算器 2.1设计思路 2.2接口设计 2.3代码实现: 2.4编译测试 总结         在之前的文章中,我们说TCP是面向字节流的,但是可能对于面向字节流这个概念,其实并不理解的,今天我们要介绍的是如何理解TCP是面向字节流的,通过编码的方式,自

    2024年02月12日
    浏览(24)
  • jackjson自定义序列化和反序列化

    JRT引用的jackjson作为json处理库。由于JRT.ORM要求表不用datetime类型,把日期和时间用Int存储,所以ORM要支持日期时间的转换。为什么要把日期时间不用datetime而用Int,比如日期:20240117,时间就是从0点到当前的秒数。因为不用datetime兼容性好,不会因为不同库datetime函数不同而要

    2024年01月18日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包