【leetcode/哈希表】寻找重复的子树(序列化表示子树)

问题描述:

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

两棵树重复是指它们具有相同的结构以及相同的结点值。

示例 1:

        1
       / \
      2   3
     /   / \
    4   2   4
       /
      4

下面是两个重复的子树:

      2
     /
    4

    4

因此,你需要以列表的形式返回上述重复子树的根结点。

基本思路:

还是利用哈希映射进行分类的思想来解这道题。问题的关键就是怎么确定分组。

大家都知道一个节点就可以代表一棵树,然而这种方法过于繁琐,原因是我们不得不通过遍历才能确定这他所代表的树。

这里我们采用二叉树的序列化的算法——把一棵二叉树表示为带空节点的前序遍历的字符串。

然后把这个作为关键字统计具有相同字符串的节点的个数。

AC代码:

/**
 * 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 {
private:
  vector<TreeNode *>res;
  unordered_map<string, int> hashmap;
public:
    string Serialize(TreeNode *root) {
    // 由于序列化的二叉树通过一个字符串就可以表示一棵树的完整信息
    // 所以我们这里才会选择序列化二叉树
    // 不然直接使用节点,我们还有对节点代表的树进行遍历,很麻烦
      if (!root) return "#";
      string temp = to_string(root->val) + "," + Serialize(root->left) + ","
              + Serialize(root->right);
      ++hashmap[temp];
      if (hashmap[temp] == 2) {
        res.push_back(root);
      }
      return temp;
    }  
  
    vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
      // 说明递归的空间浪费真的不容忽视
      // 与其多次递归,不如合并递归
      Serialize(root);
      return res;
    }
};

其它经验:

我跟人在做这道题的时候出现了MLE,这种情况真是难搞。

因为如果时TLE的话我还能改进算法,MLE我还真的不知道从何下手。

后面解决的办法就是通过合并递归的方式。

把节点序列化和将节点添加到hashmap中合为一体。

这样我们就不会堆栈溢出了。

总结就是递归会call stack overflow, 为了防止MLE,合并递归。

发布了137 篇原创文章 · 获赞 19 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43338695/article/details/102752679