LeetCode 297 Serialize and Deserialize Binary Tree

题目描述

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.

Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.

For example, you may serialize the following tree

    1
   / \
  2   3
     / \
    4   5

as “[1,2,3,null,null,4,5]”, just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.

Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

Credits:
Special thanks to @Louis1992 for adding this problem and creating all test cases.


分析

我的最开始的思路是:先求树的深度h,把树中的每个结点(2^h-1)个结点,全部记录下来,即使是null。但是这样有些极端的测试用例会超时,比如树中每个结点只有右结点,树高1000。用这种方法要遍历2^h-1次,显然能够优化。

参考 how LeetCode OJ serializes a binary tree的序列化方式,下面的二叉树,序列化后的String可以是”1,2,3,null,null,4,null,5,null”,这种方法在序列化二叉树时,只用树结点数量规模的字符即可,省时省空间。

    1
   / \
  2   3
     / 
    4   
   /
  5

代码

第一种方法:超时的代码

    // Encodes a tree to a single string.
    public static String serialize(TreeNode root) {

        if (root == null) {
            return "";
        }

        StringBuffer sb = new StringBuffer();

        Deque<TreeNode> deque = new LinkedList<TreeNode>();
        deque.add(root);

        int n = (int) (Math.pow(2, maxDepth(root)) - 1);

        while (n-- != 0) {
            TreeNode p = deque.pop();

            if (p == null) {
                sb.append(",#");
                deque.add(null);
                deque.add(null);
            } else {
                sb.append("," + p.val);
                deque.add(p.left);
                deque.add(p.right);
            }
        }

        return sb.toString().substring(1);
    }

    // Decodes your encoded data to tree.
    public static TreeNode deserialize(String data) {

        if (data == null || data.length() == 0) {
            return null;
        }

        String[] s = data.split(",");

        TreeNode[] nodeArray = new TreeNode[s.length];

        for (int i = 0; i < nodeArray.length; i++) {
            if (!"#".equals(s[i])) {
                nodeArray[i] = new TreeNode(Integer.valueOf(s[i]));
            }
        }

        for (int parent = 0; parent < s.length / 2; parent++) {

            if (nodeArray[parent] == null) {
                continue;
            }

            nodeArray[parent].left = nodeArray[parent * 2 + 1];
            nodeArray[parent].right = nodeArray[parent * 2 + 2];
        }

        return nodeArray[0];
    }

    public static int maxDepth(TreeNode root) {

        if (root == null) {
            return 0;
        }

        int nLeft = maxDepth(root.left);
        int nRight = maxDepth(root.right);

        return nLeft > nRight ? (nLeft + 1) : (nRight + 1);
    }

第二种方法,AC的代码

    public String serialize(TreeNode root) {

        if (root == null) {
            return "";
        }

        StringBuffer sb = new StringBuffer();

        Deque<TreeNode> deque = new LinkedList<TreeNode>();
        deque.add(root);

        while (!deque.isEmpty()) {
            TreeNode p = deque.pop();

            if (p == null) {
                sb.append(",#");
            } else {
                sb.append("," + p.val);
                deque.add(p.left);
                deque.add(p.right);
            }
        }

        // 第一个元素前也有一个逗号,截取
        return sb.toString().substring(1);
    }

    public TreeNode deserialize(String data) {

        if (data == null || data.length() == 0) {
            return null;
        }

        String[] s = data.split(",");

        TreeNode[] node = new TreeNode[s.length];

        // 新建TreeNode,并初始化
        for (int i = 0; i < node.length; i++) {
            if (!"#".equals(s[i])) {
                node[i] = new TreeNode(Integer.valueOf(s[i]));
            }
        }

        int parent = 0;

        // 将结点连接起来
        for (int i = 0; parent * 2 + 2 < s.length; i++) {
            if (node[i] != null) {
                node[i].left = node[parent * 2 + 1];
                node[i].right = node[parent * 2 + 2];
                parent++;
            }
        }

        return node[0];
    }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值