Letcode 652 寻找重复子树
解法并非菜鸡所想。(个人笔记,不喜勿喷)
正解:@labuladong
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
//子树计次的map表
map<string,int> CountSubTree;
//结果存储集
vector<TreeNode*> Result;
vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
SubtreeStatrics(root);
return Result;
}
string SubtreeStatrics(TreeNode* root)
{
//空的返回一个特殊符号占位
if(root==nullptr)
{
return "$";
}
//递归得到左子串
string left = SubtreeStatrics(root->left);
//递归得到右子串
string right = SubtreeStatrics(root->right);
//子树序列化。变为字符串存储
string SubTree_list = left+","+ right +","+to_string(root->val);
//取得键值对应的计次
int count_val = CountSubTree[SubTree_list];
//如果计次恒为一。说明加上这次正好出现两次,需要加入重复。如果小于1即还没有重复,大于1则已经加入过结果啦。
if(count_val==1)
{
Result.push_back(root);
}
//加入结果后将子树计次加一
CountSubTree[SubTree_list]++;
return SubTree_list;
}
};
核心思想为二叉树的序列化。进行子树的序列化,并且统计次数。和官方解法在思路上基本一致。
法二解法:@ffreturn
记录:
解题思路
子树是否相同的条件是
val相同
left和right的数值都是相同的
思路如下:
采用深度优先的方式去遍历树
去构建 包含 val,left,right 的子树的映射表, 同时这个子树需要一个编号去用于快速遍历(这里用递增的方式)
构建子树编号的映射表,初始化为1,每次找到就+1,如果=2时候说明第一次发现有重复,则插入到结果里
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
// 结果的存储
vector<TreeNode*> res;
// 子树的编号,从1开始,用0表示是无效,后续递增来保证唯一
int index = 1;
// 子树 val,left,right的字符串 到唯一编号的映射
unordered_map<string, int> str2index;
// 唯一编号 到 数量的映射
// unordered_map<int, int> index2cnt;
// 这里假设是优先编号,如5000已满足测试需求来提速
int index2cnt[5000];
// 返回值为 当前节点对应的 唯一编号
int dfs(TreeNode* curr)
{
if (curr != nullptr)
{
string currStr = to_string(curr->val) + "," + to_string(dfs(curr->left)) + "," + to_string(dfs(curr->right));
if (str2index.find(currStr) == str2index.end())
{
str2index[currStr] = index;
++index;
}
int index = str2index[currStr];
++index2cnt[index];
// 首次发现重复,增加结果里
if (index2cnt[index] == 2)
{
res.push_back(curr);
}
return index;
}
else
{
return 0;
}
}
public:
vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
dfs(root);
memset(index2cnt, 0, sizeof(int) * 5000);
return res;
}
};
作者:ffreturn
链接:https://leetcode-cn.com/problems/find-duplicate-subtrees/solution/cji-hu-shuang-bai-de-shen-du-you-xian-ji-9a82/
作者:ffreturn
链接:https://leetcode-cn.com/problems/find-duplicate-subtrees/solution/cji-hu-shuang-bai-de-shen-du-