Leetcode297:序列化和反序列化

这道题进一步考察了对二叉树的理解。
一开始此题没有做出来,最后看答案写了出来。
答案来自手画图解』二叉树的序列化与反序列化 | 剖析两种解法

答案给了广度遍历和深度遍历两种方案。
下面简略的解释一下两种解法。
总的来说,两种解法共同考虑的都是,在序列化时保护好 null 值的位置输出,来记录树的结构,以便反序列化恢复。

DFS

对于深度遍历来说,序列化的过程就是先序遍历的过程。这个无需多言。但是反序列化过程怎么做的呢?
由于序列化过程生成了大量的 null 值,导致我在反序列化过程主动放弃了这种解法。
其实在序列化过程是递归,那么反序列化同样的也是进行递归。
将序列化的字符串切割成数组,则数组第一个数即可以当成父节点。父节点之后两个数则为子节点。每次操作完前三个节点的关系后,弹出第一个节点,进入下一层递归。

BFS

这种解法,最后我的 BFS 同样会输出多余的 null 值。这让我很烦恼,因为题目给的实例里面,最后一层节点并没有发生输出。
其实 BFS 则是研究序列化后的数组的规律。
数组第一个数为父,接下来两个数为子。父亲节点索引每次 + 1,子节点索引每次 + 2。
需要注意的是,在实际编码中,千万不可通过遍历数组来创建父节点。否则各个父节点之间都是没有联系的。。。。
而应该,将上一次循环的子节点当做本次循环的父节点。这里我用了一个队列来保存父节点。

具体代码如下:

public class Answer2 {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        StringBuffer sb = new StringBuffer();
        sb.append("[");
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode poll = queue.poll();
            if (poll == null) {
                sb.append("null");
            } else {
                sb.append(String.valueOf(poll.val));
                queue.offer(poll.left);
                queue.offer(poll.right);
            }
            if (!queue.isEmpty()) {
                sb.append(",");
            }
        }
        return sb + "]";

    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        String[] nodes = data.replace("[", "").replace("]","").split(",");
        Queue<TreeNode> parent = new LinkedList<>();
        int childIndex = 1;
        TreeNode root = null;
        if (!nodes[0].equals("null")) {
            root = new TreeNode(Integer.parseInt(nodes[0]));
        }
        parent.offer(root);

        while (childIndex <= nodes.length - 1) {
            TreeNode father = parent.poll();
            if (father != null) {
                if (!nodes[childIndex].equals("null")) {
                    father.left = new TreeNode(Integer.parseInt(nodes[childIndex]));
                    parent.offer(father.left);
                }
                if (!nodes[childIndex + 1].equals("null")) {
                    father.right = new TreeNode(Integer.parseInt(nodes[childIndex + 1]));
                    parent.offer(father.right);
                }
            }
            childIndex += 2;
        }
        return root;
    }
}

具体参考上面引用的文章,说明得很详细。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值