LeetCode 652: 尋找重複的子樹 Find Duplicate Subtrees
題目:
給定一棵二叉樹,返回全部重複的子樹。對於同一類的重複子樹,你只須要返回其中任意一棵的根結點便可。java
兩棵樹重複是指它們具備相同的結構以及相同的結點值。node
Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node of any one of them.python
Two trees are duplicate if they have the same structure with same node values.數組
示例 1:微信
1 / \ 2 3 / / \ 4 2 4 / 4
下面是兩個重複的子樹:app
2 / 4
和code
4
所以,你須要以列表的形式返回上述重複子樹的根結點。orm
Therefore, you need to return above trees' root in the form of a list.遞歸
解題思路:
這就是一道考察二叉樹遍歷的題, 遍歷的時候序列化做爲 String 類型存入 Map, 若其爲第二次出現即將該結點加入數組.get
代碼:
這裏之後序遍歷爲例, 須要注意葉子結點應當規定一個特殊字符做爲替代 null 結點, 這裏用的是 '#'
Java:
class Solution { public List<TreeNode> findDuplicateSubtrees(TreeNode root) { List<TreeNode> list = new ArrayList<>();//待返回數組 if (root == null) return list; Map<String, Integer> map = new HashMap<>();//哈希映射查找重覆子結點 traverse(root, map, list, ""); return list; } //後序遍歷 private String traverse(TreeNode node, Map<String, Integer> map, List<TreeNode> list, String tree) { if (node == null) return tree + "#"; String left = traverse(node.left, map, list, tree);//遞歸左子孩子 String right = traverse(node.right, map, list, tree);//遞歸右子孩子 tree = tree + node.val + left + right;//每一個子樹路徑 map.put(tree, map.getOrDefault(tree, 0) + 1);//存儲每一個子樹路徑 if (map.get(tree) == 2) list.add(node);//第二次出現相同路徑時存儲該結點 return tree; } }
Python:
class Solution: def findDuplicateSubtrees(self, root: TreeNode) -> List[TreeNode]: res = [] # 待返回數組 if not root: return res hash_map = {} # 哈希映射查找重覆子結點 self.traverse(root, hash_map, res, '') return res # 後序遍歷 def traverse(self, node: TreeNode, hash_map, res, tree): if not node: return tree + '#' left = self.traverse(node.left, hash_map, res, tree) # 遞歸左子孩子 right = self.traverse(node.right, hash_map, res, tree) # 遞歸右子孩子 tree = tree + str(node.val) + left + right # 每一個子樹路徑 if tree in hash_map.keys(): # 存儲每一個子樹路徑 hash_map[tree] += 1 else: hash_map[tree] = 1 if hash_map[tree] == 2: # 第二次出現相同路徑時存儲該結點 res.append(node) return tree
歡迎關注微信公衆號: 愛寫Bug