在LeetCode第一次寫出400+ms時間 360+MB內存的代碼。。。。。

在這裏插入圖片描述
第一次寫出這麼慢的代碼,看到這個速度和內存消耗,不禁陷入了沉思。。。。。。我還以爲我寫了一整個遊戲出來,畢竟360多MB的內存消耗,有點誇張。
果然不能濫用java的集合類。
貼出代碼慢慢優化。。。
LeetCode449

public class Codec {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        return serializeCore(root, sb);
    }

    private String serializeCore(TreeNode root, StringBuilder sb) {
        if (root == null){
            sb.append("#,");
        }else {
            sb.append(root.val).append(",");
            serializeCore(root.left, sb);
            serializeCore(root.right, sb);
        }

        return String.valueOf(sb);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
    //一看估計就是這裏慢的要死,說實話用着還挺方便的
        String[] strings = data.split(",");
        LinkedList<String> list = new LinkedList<>();
        Collections.addAll(list, strings);

        return deserializeCore(list);
    }

    private TreeNode deserializeCore(LinkedList<String> sb) {
        if (sb.get(0).equals("#")){
            sb.remove(0);
            return null;
        }
        TreeNode root = new TreeNode(Integer.parseInt(sb.get(0)));
        sb.remove(0);
        root.left = deserializeCore(sb);
        root.right = deserializeCore(sb);

        return root;
    }
}

先從遞歸入手吧,改成非遞歸的層次遍歷吧
好了,序列化的改成層次遍歷完成,將null結點替換爲#字符。

public static String serialize(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            if (node == null){
                sb.append("#,");
            }else {
                sb.append(node.val).append(",");
                queue.offer(node.left);

                queue.offer(node.right);

            }
        }
        return sb.toString();
    }

下面是反序列化過程,其實思路不難。

public TreeNode deserialize(String data) {
        String[] strings = data.split(",");
        if (strings.length == 1 && strings[0].equals("#")){
            return null;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        TreeNode head = new TreeNode(Integer.parseInt(strings[0]));
        queue.offer(head);
        int index = 1;
        while (index < strings.length) {
            TreeNode node = queue.poll();
            if (node != null) {
                TreeNode left = strings[index].equals("#") ? null : new TreeNode(Integer.parseInt(strings[index]));
                index++;
                queue.offer(left);
                node.left = left;

                TreeNode right = strings[index].equals("#") ? null : new TreeNode(Integer.parseInt(strings[index]));
                index++;
                queue.offer(right);
                node.right = right;
            }
        }
        return head;
    }

再次提交:進步很大,不過相比還是慢了,唯一可能的點可能就在於split()方法了
在這裏插入圖片描述
繼續改進split()這個點,爲什麼需要這個方法,因爲一個個取出String data裏的值,換一種方式來看看。
如果是"2,1,3,4,5,#,#,7,#,#,#,#,#,"序列化的結果,這好說,直接隔着兩個取,但是如果是多位數了,則需要掃描直到“,”爲止,涉及到了字符串轉整數,感覺有點偏離題意了。
所以上面的方法也就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章