652. 寻找重复的子树

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

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

示例 1:

        1
       / \
      2   3
     /   / \
    4   2   4
       /
      4
下面是两个重复的子树:

      2
     /
    4

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-duplicate-subtrees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法:

class Solution {
public:
    vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) 
    {
        vector<TreeNode*> res;
        unordered_map<string, int> m;
        helper(root, m, res);
        return res;
    }
    string helper(TreeNode* node, unordered_map<string, int>& m, vector<TreeNode*>& res) 
    {
        if (!node) return "#";
        string str = to_string(node->val) + "," + helper(node->left, m, res) + "," + helper(node->right, m, res);
        if (m[str] == 1) res.push_back(node);
        ++m[str];
        return str;
    }
};

 

### 二叉树中插入子树的算法 在二叉树的数据结构中,插入子树的操作通常涉及以下几个方面:定位父节点、调整指针以及维护树的整体性质。以下是基于 C++ 的一种实现方法。 #### 定位父节点 为了在二叉树中插入一个新的子树,首先需要找到目标父节点的位置。这可以通过遍历整棵树来完成,具体可以选择前序、中序或后序遍历来查找指定的关键字作为父节点[^1]。 #### 调整指针 一旦找到了合适的父节点,就需要决定新子树应该成为该父节点的左孩子还是右孩子。如果父节点原本已经有相应的子树,则可能需要将其替换或将旧子树移动到其他地方保存[^4]。 #### 维护树的性质 对于普通的二叉树而言,在插入新的子树之后无需特别考虑平衡性等问题;但如果是在特殊类型的二叉树(如AVL树)中执行此操作,则还需要额外注意保持树的高度平衡特性[^3]。 下面给出一段简单的C++代码示例用于演示如何在一个已存在的二叉树内部插入另一棵完整的子树: ```cpp struct TreeNode { int val; TreeNode* left; TreeNode* right; explicit TreeNode(int x):val(x),left(nullptr),right(nullptr){} }; // 函数功能:寻找key所在的结点并返回其地址; TreeNode *findNode(TreeNode *root, const int &key){ if(!root || root->val==key)return root; // 找到了或者没找到都返回当前node auto res=findNode(root->left,key); if(res!=nullptr)return res;// 如果左边存在就不继续找右边了 return findNode(root->right,key); } void insertSubtreeAtKey(const int key, TreeNode *&subRoot, TreeNode *&targetTree){ TreeNode *parent=findNode(targetTree,key); if(parent && !parent->left){ parent->left=subRoot;} else if(parent&&!parent->right){ parent->right=subRoot;} } ``` 以上代码片段展示了如何定义一个`TreeNode`类表示单个节点,并提供了两个辅助函数分别用来搜索特定键值所在位置(`findNode`) 和实际进行子树插入 (`insertSubtreeAtKey`) 。需要注意的是这里假设待插入的目标树不含有重复关键字的情况发生[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值