题目描述
给定一棵二叉树 root,返回所有重复的子树。
对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。
如果两棵树具有相同的结构和相同的结点值,则它们是重复的。
示例1:
输入:root = [5,4,2,1,null,4,1,null,null,1] 输出:[[4,1],[1]]
解题思路
- 这里使用HashMap来做去重处理;
- 使用递归来记录每个根节点的字符串;
按照示例1,对每个节点做遍历后效果:
- 1()()
- 4(1()())()
- 1()()
- 4(1()())()
- 1()()
- 2(4(1()())())(1()())
- 5(4(1()())())(2(4(1()())())(1()()))
其中1()()出现了3次,4(1()())()出现了2次,其他的出现了1次,根据题目要求返回1()() 和 4(1()())()对应的节点。
代码实现
class Solution {
Set<TreeNode> res = new HashSet<>();
Map<String, TreeNode> map = new HashMap<String, TreeNode>();
public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
dfs(root);
return new ArrayList<>(res);
}
private String dfs(TreeNode root) {
if (root == null) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append(root.val);
sb.append("(");
sb.append(dfs(root.left));
sb.append(")(");
sb.append(dfs(root.right));
sb.append(")");
String s = sb.toString();
if (map.get(s) != null) {
res.add(map.get(s));
} else {
map.put(s, root);
}
return s;
}
}
总结
这道题是二叉树遍历的变体,考察核心如何遍历每个节点,并且做去重操作;如果有更加简洁、高效的思路欢迎回复。