↓快轉到主要內容
  1. LeetCode/

LeetCode 652: Find Duplicate Subtrees

·1 分鐘· ·
LeetCode Medium Hash-Table Tree Depth-First-Search Binary-Tree
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2026-10-26

  • 提交紀錄:Accepted ×2

解題思路
#

兩棵子樹相同,等於它們的「編碼」相同。後序 DFS(Tree 模板一):先拿到左右子樹的編碼,再組出自己的編碼,用雜湊表計數(Hash Table 模板五,正規化之後當 key)。某個編碼出現第二次時,把這個節點加入答案,之後再出現就不加,避免重複。

編碼要能唯一代表結構,所以空節點也要寫出來。

我的嘗試
#

兩次都一次通過:

  1. 10-26:編碼是字串 f"{val},{left},{right}",空節點是 #。
  2. 10-27:改成把 (val, 左 id, 右 id) 映射到一個整數 id,避免字串越接越長。

正確解法
#

class Solution:
    def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]:
        tree_id = {}
        count = defaultdict(int)
        res = []

        def post(node):
            if not node:
                return 0
            key = (node.val, post(node.left), post(node.right))
            if key not in tree_id:
                tree_id[key] = len(tree_id) + 1
            uid = tree_id[key]
            count[uid] += 1
            if count[uid] == 2:
                res.append(node)
            return uid

        post(root)
        return res

複雜度
#

編碼時間
字串最差 O(n^2):每個節點的字串長度和子樹大小成正比
(值, 左 id, 右 id) → idO(n):每個 key 是固定大小的 tuple

空間都是 O(n)。

要特別避免的錯誤
#

  • 用 == 2 才加入,不要用 >= 2,不然同一種子樹會被加很多次。
  • 只用中序就算加上空節點也會撞:[0,0] 和 [0,null,0] 的中序都是 #,0,#,0,#。要用前序或後序。

面試口說整理
#

我用後序 DFS 幫每棵子樹做編碼,空節點也算進去,用雜湊表計數,出現第二次就把節點加入答案。字串編碼最差 O(n^2),所以我把 (值, 左子樹 id, 右子樹 id) 映射成整數 id,每個節點只做常數工作,總共 O(n)。

相關文章

LeetCode 314: Binary Tree Vertical Order Traversal
·1 分鐘
LeetCode Medium Hash-Table Tree Depth-First-Search Breadth-First-Search Sorting Binary-Tree
LeetCode 314 解題筆記:BFS 帶著欄位編號,用 BFS 才能保證同一欄由上到下、同一列由左到右
LeetCode 449: Serialize and Deserialize BST
·1 分鐘
LeetCode Medium String Tree Depth-First-Search Breadth-First-Search Design Binary-Search-Tree Binary-Tree
LeetCode 449 解題筆記:BST 只要存前序,不用空節點標記;反序列化帶著上下界遞迴,O(n)
LeetCode 99: Recover Binary Search Tree
·1 分鐘
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 99 解題筆記:中序遍歷找逆序:第一次逆序的前一個、最後一次逆序的後一個,就是被交換的兩個節點
LeetCode 1372: Longest ZigZag Path in a Binary Tree
·1 分鐘
LeetCode Medium Dynamic-Programming Tree Depth-First-Search Binary-Tree Dp-on-Trees
LeetCode 1372 解題筆記:每個節點回傳兩個值:從這裡先往左、先往右的最長 zigzag;往左走接的是左小孩「先往右」的值
LeetCode 515: Find Largest Value in Each Tree Row
·1 分鐘
LeetCode Medium Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 515 解題筆記:BFS 層序遍歷,每層取最大值;初始值用 -inf
LeetCode 687: Longest Univalue Path
·1 分鐘
LeetCode Medium Tree Depth-First-Search Binary-Tree Dp-on-Trees
LeetCode 687 解題筆記:DFS 回傳往下同值的最長鏈(邊數),在每個節點用左 + 右更新答案