原题链接:. - 力扣(LeetCode)
给你一棵二叉树的根节点 root
,返回所有 重复的子树 。
对于同一类的重复子树,你只需要返回其中任意 一棵 的根结点即可。
如果两棵树具有 相同的结构 和 相同的结点值 ,则认为二者是 重复 的。
示例 1:
输入:root = [1,2,3,4,null,2,4,null,null,4] 输出:[[2,4],[4]]
示例 2:
输入:root = [2,1,1] 输出:[[1]]
示例 3:
输入:root = [2,2,2,3,null,3,null] 输出:[[2,3],[3]]
提示:
- 树中的结点数在
[1, 5000]
范围内。 -200 <= Node.val <= 200
思路:
本题需要找到重复的子树,那么需要解决两个问题。一、如何知道 以当前节点为根节点的子树的结构。二、如何知道以当前节点为根节点的子树 是否重复出现过。
对于第一个问题,可以通过序列化表示出当前子树的结构。对于每一个节点,利用一个序列化字符串标识其结构,可以通过 前序、中序、后序或者层序遍历,本文采用后序遍历。
对于第二个问题,可以通过一个 HashMap 来去重。当一个结构出现第二次的时候,将这个结构所在的根节点加入到 结果集中,这个结构出现更多次的时候不能重复添加。
代码:
class Solution {Map<String,Integer> map = new HashMap<>();List<TreeNode> ans = new LinkedList<>();public List<TreeNode> findDuplicateSubtrees(TreeNode root) {find(root);return ans;}public String find(TreeNode root){if(root==null){return "#";}String left = find(root.left);String right= find(root.right);//myself是以当前节点为根节点的子树的后序序列化表示String myself = left+","+right+","+root.val;int freq = map.getOrDefault(myself,0);if(freq==1){ans.add(root);}map.put(myself,freq+1);//返回以当前节点为根节点的子树的结构return myself;}
}
参考:东哥带你刷二叉树(后序篇) | labuladong 的算法笔记