Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】

题目

请实现两个函数,分别用来序列化和反序列化二叉树。

你需要设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

提示:输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

示例:

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第1张图片

输入:root = [1,2,3,null,null,4,5]
输出:[1,2,3,null,null,4,5]

 

解题思路

1.题目要求我们实现两个函数,分别用来序列化和反序列化二叉树。首先我们来实现序列化二叉树,也就是将二叉树的层序遍历变为一个数组,那我们就需要用一个StringBuilder (res)来拼接遍历到的元素,还需要一个队列 queue 来按照层序遍历来遍历二叉树,首先我们将根节点放入 queue 中,当 queue不为null,我们就让queue中的元素出队,然后判断当前出队元素是否为null,若当前出队元素不为null,我们就将当前出队元素与“,”(逗号)拼接到 StringBuilder (res)中,然后再将当前出队元素的左右孩子加入队列中。若当前出队元素为 null,我们就将 “null,”拼接到 queue 中。最后我们将多余的“,”删除,并且加上“]”,然后返回即可。

2.反序列化的实现有一点复杂我们画图来看,

举个例子:

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第2张图片

 实现反序列化我们依旧需要一个队列 queue,然后将所给的数组去除逗号后将它保存在数组vals中,我们知道层序遍历的第一个元素是二叉树的根节点,所以我们先让 vals[0] 入队。同时设置一个变量i = 1(遍历数组用)。

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第3张图片

 当队列queue不为null时,我们让队头元素出列(2出列),这时 i 指向的元素不为 null 恰好是(2)的左孩子,所以我们就要令(2) 的左孩子指向(3),并且让(3)入队。然后我让 i 后移一位,

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第4张图片

 这时 i 指向的元素不为 null 恰好是(2)的右孩子,所以我们就要令(2) 的右孩子指向(4),并且让(4)入队。然后我让 i 后移一位,

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第5张图片

 queue不为null,我们让队头元素出列(3出列),这时 i 指向的元素不为 null 恰好是(3)的左孩子,所以我们就要令(3) 的左孩子指向(5),并且让(5)入队。然后我让 i 后移一位,

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第6张图片 这时 i 指向的元素为 null ,我们不做任何操作,因为(3)的右孩子(node.right)初始值就为null,我直接将 i 后移一位,

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第7张图片

 queue不为null,我们让队头元素出列(4出列),这时 i 指向的元素不为 null 恰好是(4)的左孩子,所以我们就要令(4) 的左孩子指向(6),并且让(6)入队。然后我让 i 后移一位, Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第8张图片

 i 指向的元素为 null ,我们不做任何操作,接将 i 后移一位,

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第9张图片

 queue不为null,我们让队头元素出列(5出列), i 指向的元素为 null ,我们不做任何操作,接将 i 后移一位,

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第10张图片

 i 指向的元素为 null ,我们不做任何操作,接将 i 后移一位,

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第11张图片  queue不为null,我们让队头元素出列(6出列), i 指向的元素为 null ,我们不做任何操作,接将 i 后移一位,

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第12张图片  i 指向的元素为 null ,我们不做任何操作,接将 i 后移一位,

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第13张图片

代码实现

public class Codec {
    public String serialize(TreeNode root) {
        if(root == null) return "[]";
        StringBuilder res = new StringBuilder("[");
        Queue queue = new LinkedList<>() {{ add(root); }};
        while(!queue.isEmpty()) {
            TreeNode node = queue.poll();
            if(node != null) {
                res.append(node.val + ",");
                queue.add(node.left);
                queue.add(node.right);
            }
            else res.append("null,");
        }
        res.deleteCharAt(res.length() - 1);
        res.append("]");
        return res.toString();
    }
    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if(data.equals("[]")) return null;
        String[] vals = data.substring(1, data.length() - 1).split(",");
        TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
        Queue queue = new LinkedList<>() {{ add(root); }};
        int i = 1;
        while(!queue.isEmpty()) {
            TreeNode node = queue.poll();
            if(!vals[i].equals("null")) {
                node.left = new TreeNode(Integer.parseInt(vals[i]));
                queue.add(node.left);
            }
            i++;
            if(!vals[i].equals("null")) {
                node.right = new TreeNode(Integer.parseInt(vals[i]));
                queue.add(node.right);
            }
            i++;
        }
        return root;
    }
}

测试结果

Leetcode-每日一题【剑指 Offer 37. 序列化二叉树】_第14张图片

 

你可能感兴趣的:(leetcode,算法,职场和发展,java)