LeetCode剑指offer Q37 序列化二叉树 bug解法

思路

看到题目给的例子时,我以为在序列化时时将整棵树作为满二叉树来序列化,但是在测试时发现并不是,它只是判断每个节点的左右子树是否为null,如果是则添加为null。但是本题有一些bug,第一个:序列化函数中将最后一层叶子结点的子树也进行了序列化,这种结果官方并不算错,但严格意义上需要将最后的null都消除。bug的原因是这一题测试时是调用的

// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));

所以不论怎样序列化,只要保证反序列化出来的结果和给的用例root相同即可,这样便想出了一个简单套路:

TreeNode root;
    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        this.root=root;
        return "";
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        return this.root;
    }

直接将root原样返回即可,这样效率基本100%。不过未来估计官方会封堵这个漏洞的。

正经的思路:
序列化:

很简单的使用层次遍历即可,从queue中取出结点cur,若cur为null,则添加null,否则添加cur.val。

反序列化:

还是使用层次遍历,但是要添加一个指示变量index,用来标示当前结点的子结点位置,index每次走两步。

代码:

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

        }

        sf.replace(sf.length() - 1, sf.length(), "]");
        return sf.toString();
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        int len = data.length();
        if (len == 2 || len == 0) return null;
        data = data.substring(1, len - 1);
        String[] vals = data.split(",");
        Queue<TreeNode> q = new LinkedList<>();
        int index = 0;
        TreeNode root = new TreeNode(Integer.parseInt(vals[index++]));
        q.add(root);
        while (!q.isEmpty()) {
            TreeNode cur = q.poll();
            if(cur==null) continue;
            System.out.println(cur.val + "," + index);
            if (index >= vals.length) break;
            cur.left = generalizeNode(vals[index++]);
            if (index >= vals.length) break;
            cur.right = generalizeNode(vals[index++]);
            //if (cur.left != null)
                q.add(cur.left);
            //if (cur.right != null)
                q.add(cur.right);
        }

        return root;

    }

    TreeNode generalizeNode(String value) {
        if (value.equals("null")) return null;
        return new TreeNode(Integer.parseInt(value));
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值