好友抖音面試真題:二叉樹的序列化與反序列化(解法二)

前言

以前分享了朋友面試抖音的真題:LeetCode 297. 二叉樹的序列化與反序列化,我用的BFS(廣度優先遍歷)的方法來作的。事實上,朋友在面試的時候也是用BFS來作的。html

BFS的解法點擊跳轉:好友抖音面試真題:297.二叉樹的序列化與反序列化java

BFS的運行結果其實不算很滿意,因此今天我又用DFS(深度優先遍歷)來從新作了一遍,兩種方法的耗時對比:面試

能夠看出,DFS是要比BFS快很多的,因此分享下DFS的解法。markdown

題目

仍是先看看題目:app

前序遍歷

這裏就不贅述了,直接上代碼:oop

private void ser(StringBuilder sb, TreeNode root) {
    if (root == null) {
        sb.append("nil,");
        return;
    }
    sb.append(root.val).append(",");
    ser(sb, root.left);
    ser(sb, root.right);
}

// Encodes a tree to a single string.
public String serialize(TreeNode root) {
    StringBuilder sb = new StringBuilder();
    ser(sb, root);
    return sb.substring(0, sb.length() - 1);
}
複製代碼

這裏碰到爲空的狀況,須要把結果拼接成nil,好讓重構二叉樹的時候能夠知道哪些節點是沒有左右孩子的。ui

反序列化

題目所給的那棵樹序列化:spa

前序遍歷是先 根,而後左右。那麼重建的時候也是先根後左右:3d

  1. build(1) // root節點
  2. 開始考慮root的左孩子:build(2)
  3. 開始考慮2的左孩子:build(nil) // 碰到nil就沒了。而後考慮2的右孩子,也是nil。到這裏這條路徑就結束了
  4. root節點的左孩子考慮完以後,要開始考慮root的右孩子了:build(3)
  5. 而後再考慮3的左孩子:build(4); 3的右孩子:build(5)
  6. 以此類推。

說白了,其實跟前序遍歷的遞歸過程是同樣的。code

因此直接上代碼去感覺下:

private TreeNode des(LinkedList<String> strings) {
    // 依次取出每個元素
    String poll = strings.poll();
    // 若是沒有了或者 爲nil,那麼返回 null
    if (poll == null || "nil".equals(poll)) {
        return null;
    }
    // 構建當前節點
    TreeNode root = new TreeNode(Integer.parseInt(poll));
    // 構建當前節點的左孩子
    root.left = des(strings);
    // 構建當前節點的右孩子
    root.right = des(strings);
    // 把當前節點返回出去。(返回出去就變成了它上一個節點的左右孩子了/或者自己就是root節點)
    return root;
}

// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
    if (data == null || data.isEmpty()) {
        return null;
    }
    LinkedList<String> strings = new LinkedList<>(Arrays.asList(data.split(",")));
    return des(strings);
}
複製代碼

總結

遞歸是一個比較抽象的東西,也很難給講得透徹。因此對於這種作法,仍是須要多琢磨。琢磨透了,下次作題也仍是不會,hahaha~~~

謝絕轉載

【Happyjava】原創文章,未經容許,謝絕轉載!

相關文章
相關標籤/搜索