【问题标题】:Serialize and Deserialize Binary Tree序列化和反序列化二叉树
【发布时间】:2021-11-14 02:37:06
【问题描述】:

我正在解决 LeetCode 问题297. Serialize and Deserialize Binary Tree:

序列化是将数据结构或对象转换为位序列的过程,以便将其存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一或另一个计算机环境中重建.

设计一种算法来序列化和反序列化二叉树。您的序列化/反序列化算法的工作方式没有限制。你只需要保证一棵二叉树可以序列化成一个字符串,并且这个字符串可以反序列化成原来的树结构。

我从 Geeks for Geeks 上发现的一个类似问题的正确解决方案中获得灵感:Serialize and Deserialize a Binary Tree :

class Tree 
{
    public void serialize(Node root, ArrayList<Integer> al) 
    {
        //code here
        if(root == null) {
            al.add(-1);
            return;
        }
        al.add(root.data);
        serialize(root.left,al);
        serialize(root.right,al);
    }
    

    public Node deSerialize(ArrayList<Integer> al)
    {
        //code here
        if(al.get(0) == -1) {
            al.remove(0);
            return null;
        }
        Node newNode = new Node(al.get(0));
        al.remove(0);
        newNode.left = deSerialize(al);
        newNode.right = deSerialize(al);
        return newNode;
    }
}

我尝试针对 LeetCode 问题调整这种方法。但是,我的尝试没有产生所需的输出:

public class Codec {
    StringBuilder sb = new StringBuilder();
    public String serialize(TreeNode root) {
        if(root==null) {
            sb.append("^");
            return sb.toString();
        }
        sb.append(String.valueOf(root.val));
        serialize(root.left);
        serialize(root.right);
        return sb.toString();
    }
    public TreeNode deserialize(String data) {
        if(data.charAt(0)=='^') {
            data = data.substring(1);
            return null;
        }
        TreeNode newNode = new TreeNode(Character.getNumericValue(data.charAt(0)));
        data = data.substring(1);
        newNode.left = deserialize(data);
        newNode.right = deserialize(data);
        return newNode;
    }
}

我哪里做错了?

【问题讨论】:

  • 你正在调用serialize(...),但你没有对返回值做任何事情。它应该是sb.append(serialize(...))。除此之外,您还需要将 stringBuilder 的创建移到 serialize 函数中。
  • 下面的例子有效,因为你没有返回值,你正在写入传递的arrayList

标签: java serialization tree binary-tree binary-search-tree


【解决方案1】:

一些备注:

  • Geeks-for-Geeks 问题有一个不同的接口:“序列化”被解释为将信息存储在一个数组(向量)中,而对于 LeetCode 问题,序列化是关于生成一个字符串。

  • 您的代码有一个sb 成员,可以在第二次调用serialize 时重复使用该成员。然而serialize 的正确功能至少需要sb 最初代表一个空字符串。

  • String.valueOf(root.val) 被附加,但两个连续的字符串化值之间没有分隔符,因此deserialize 将不知道有多少位数字属于一个值。实际上,您的 deserialize 似乎假设每个数字仅包含一位数字。这不能假设。

  • deserialize 中,赋值data = data.substring(1) 只会影响局部变量data,不会影响调用者data 变量。请注意 Geeks-for-Geeks 解决方案的优势在于它可以使用 array,它可以mutate。字符串是不可变的,所以在 LeetCode 问题中我们不能使用这种策略。您可以使用第三个函数来摆脱这种情况,传递一个可变数组。

例如:

public class Codec {
    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if (root == null) {
            return "^";
        }
        return String.valueOf(root.val) + ","
             + serialize(root.left) + ","
             + serialize(root.right);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        return deserializeArray(new ArrayList<String>(Arrays.asList(data.split(","))));
    }
    
    private TreeNode deserializeArray(ArrayList<String> arr) {
        String value = arr.remove(0);
        if (value.charAt(0) == '^') {
            return null;
        }
        TreeNode node = new TreeNode(Integer.parseInt(value));
        node.left = deserializeArray(arr);
        node.right = deserializeArray(arr);
        return node;
    }
}

【讨论】:

    猜你喜欢
    • 2019-01-26
    • 2020-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    相关资源
    最近更新 更多