给定一棵二叉树,返回所有重复的子树。对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。
两棵树重复是指它们具有相同的结构以及相同的结点值。
示例 1:
1
/ \
2 3
/ / \
4 2 4
/
4
下面是两个重复的子树:
2
/
4
和
4
因此,你需要以列表的形式返回上述重复子树的根结点。
思路:
没有想到的地方有两点:
1是子树的存储方式,这里采用的是string来存储每个子树结构,当然也可构造一个三元组{root->val,root->left,root->right}来存。为了避免重复,只用统计出现过两次的子树结构。
2只用判断根节点和他的下一层子树两层,如对于:
1
/ \
2 3
/ / \
4 2 4
/ /
5 4
/
5
这种情况,虽然[2,4,null,5,null]在根节点1的左右子树都出现了,但这时候重复子树的个数算[2,4,null]和[4,5,null]两个,而不是[2,4,null,5,null]一个子树。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
vector<TreeNode*> ans;
if(root==NULL) return ans;
unordered_map<string,int> mp;
dfs(root,ans,mp);
return ans;
}
string dfs(TreeNode* root,vector<TreeNode*> &ans,unordered_map<string,int> &mp){
if(root==NULL) return "#";
string tmp=to_string(root->val)+dfs(root->left,ans,mp)+dfs(root->right,ans,mp);
if(mp[tmp]==1) ans.push_back(root);
mp[tmp]++;
return tmp;
}
};