leetcode每日一题【寻找重复的子树】2022/09/05

发布于:2022-12-28 ⋅ 阅读:(446) ⋅ 点赞:(0)

一、652. 寻找重复的子树【中】

1、题目:

给定一棵二叉树 root,返回所有重复的子树。

对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。

如果两棵树具有相同的结构和相同的结点值,则它们是重复的。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/special-positions-in-a-binary-matrix

我的思路是深度优先,去用数组记录每个节点的左右子树。如下图,值为3的结点左子树为[4,2],右子树为[4]。这样很直观能看出哪些子树是相等的,但在程序上引来两个问题:

  • 数组个数会有多个,如何知道这些数组哪些是相等的?
  • 知道了相等的两个数组后,怎么知道这个数组是哪个节点的子树?
    在这里插入图片描述

2、思路一:深度优先+字符串哈希表

依然是深度优先,不同的是数组被替换成了字符串去描述一颗子树,再使用字符串哈希表,记录每种子树出现的次数,若在遍历过程中,子树字符串出现次数等于两次时,即记录该节点。
等于是因为,若多个子树是相同的,只需要返回一个子树的根即可。

代码(错误):

class Solution {
public:
    vector<TreeNode*> result; //结果节点
    vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
        unordered_map<string,int> map; //记录子树出现次数的字符串哈希表
        dfs(root,map); 
        return result;
    }
    //dfs
    string dfs(TreeNode* node, unordered_map<string,int>& map){
        if(!node) return "";
        string left = dfs(node->left, map);
        string right = dfs(node->right, map);
        string current = left+to_string(node->val)+right;
        map[current] ++; // 记录该子树
        if(map[current]==2) result.push_back(node); // 出现次数为2次
        return current;
    }
};

在这里插入图片描述
思路没问题,但代码错了,该例子可视化后:
在这里插入图片描述
发现,子树也需要区分左右。那么在每次将左子树、右子树、节点连接成子树字符串返回上层时,左子树前加“(”,右子树前加“)”即可。
官解分析的时间复杂度:
在这里插入图片描述

代码:

//s:O(n) t:O(n)
class Solution {
public:
    vector<TreeNode*> result; //结果节点
    vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
        unordered_map<string,int> map; //记录子树出现次数的字符串哈希表
        dfs(root,map); 
        return result;
    }
    //dfs
    string dfs(TreeNode* node, unordered_map<string,int>& map){
        if(!node) return "";
        string left = "("+dfs(node->left, map);
        string right = ")"+dfs(node->right, map);
        string current = left+to_string(node->val)+right;
        map[current] ++; // 记录该子树
        if(map[current]==2) result.push_back(node); // 出现次数为2次
        return current;
    }
};

3、思路二 :使用三元组进行唯一表示(待定)

例子:

代码:

//s:O() t:O()
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到