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)

猜你喜欢

转载自blog.csdn.net/weixin_43141320/article/details/113817546