652.寻找重复的子树

题目链接

深度优先(C++)

解题思路:将每一棵子树序列化,即对于一棵子树,转化为:
s t r i n g ( r o o t ) + s t r i n g ( r o o t . l e f t ) + s t r i n g ( r o o t . r i g h t ) string(root)+string(root.left)+string(root.right) string(root)+string(root.left)+string(root.right)
对于这个序列需要使用一个散列表来储存其出现的次数,如果次数为1,即之前遇到过一次,就将该根节点放入结果列表中;否则不放入。

必备C++STL知识:map和unorderedmap的区别和使用

class Solution {
public:
    vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
        vector<TreeNode*> res;  // 存放结果根节点
        unordered_map<string, int> mp;  // 存放序列化子树的出现次数
        helper(root, mp, res);
        return res;
    }
    string helper(TreeNode* root, unordered_map<string, int>&mp, vector<TreeNode*>&res){
        if(!root) return "#";
        string str;
        // 序列化子树
        str = to_string(root->val) + ' ' + helper(root->left, mp, res) + ' '+ helper(root->right, mp, res);
        // 如果str不存在mp中,mp[str]==0
        if(mp[str] == 1) res.push_back(root);
        mp[str]++;
        return str;
    }
};

深度优先(python)

思路和递归实现的C++版本一致:

python必备知识:collections.defaultdict的使用1
collections.defaultdict的使用2
python的collections库的使用1
python的collections库的使用2

class Solution:
    def findDuplicateSubtrees(self, root: TreeNode) -> List[TreeNode]:
        cnt = collections.Counter()
        res = []
        def helper(root):
            if not root:
                return '#'
            string = "{:},{:},{:}".format(root.val, helper(root.left), helper(root.right))
            if cnt[string] == 1:
                res.append(root)
            cnt[string]+=1
            return string
        helper(root)
        return res

时间复杂度: O ( N 2 ) O(N^2) O(N2),其中 N N N 是二叉树上节点的数量。遍历所有节点,在每个节点处序列化需要时间 O ( N ) O(N) O(N)

空间复杂度: O ( N 2 ) O(N^2) O(N2) c o u n t count count 的大小。

唯一标识符

class Solution(object):
    def findDuplicateSubtrees(self, root):
        trees = collections.defaultdict()
        trees.default_factory = trees.__len__
        count = collections.Counter()
        ans = []
        def lookup(node):
            if node:
                uid = trees[node.val, lookup(node.left), lookup(node.right)]
                count[uid] += 1
                if count[uid] == 2:
                    ans.append(node)
                return uid

        lookup(root)
        return ans

时间复杂度: O ( N ) O(N) O(N),其中 N N N二叉树上节点的数量,每个节点都需要访问一次。
空间复杂度: O ( N ) O(N) O(N),每棵子树的存储空间都为 O ( 1 ) O(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值