int count(TreeNode root) {
if (root == null)
{ return 0; }
// 先算出左右子树有多少节点
int left = count(root.left);
int right = count(root.right);
/* 后序遍历代码位置 */
// 加上自己,就是整棵二叉树的节点数
int res = left + right + 1;
return res;
}
String traverse(TreeNode root) {
// 对于空节点,可以用一个特殊字符表示
if (root == null)
{ return "#"; }
// 将左右子树序列化成字符串
String left = traverse(root.left);
String right = traverse(root.right);
/* 后序遍历代码位置 */
// 左右子树加上自己,就是以自己为根的二叉树序列化结果
String subTree = left + "," + right + "," + root.val;
return subTree;
}
// 记录所有子树
HashSet<String> memo = new HashSet<>();
// 记录重复的子树根节点
LinkedList<TreeNode> res = new LinkedList<>();
String traverse(TreeNode root) {
if (root == null)
{ return "#"; }
String left = traverse(root.left);
String right = traverse(root.right);
String subTree = left + "," + right+ "," + root.val;
if (memo.contains(subTree)) { /
/ 有人和我重复,把自己加入结果列表
res.add(root);
} else
{ /
/ 暂时没人跟我重复,把自己加入集合
memo.add(subTree);
}
return subTree;
}
// 记录所有子树以及出现的次数
HashMap<String, Integer> memo = new HashMap<>();
// 记录重复的子树根节点
LinkedList<TreeNode> res = new LinkedList<>();
/* 主函数 */
public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
traverse(root);
return res;
}
/* 辅助函数 */
String traverse(TreeNode root) {
if (root == null) {
return "#";
}
String left = traverse(root.left);
String right = traverse(root.right);
String subTree = left + "," + right+ "," + root.val;
int freq = memo.getOrDefault(subTree, 0);
// 多次重复也只会被加入结果集一次
if (freq == 1) {
res.add(root);
}
// 给子树对应的出现次数加一
memo.put(subTree, freq + 1);
return subTree;
}