• 力扣每日一题2022-09-05中等题:寻找重复的子树



    题目描述

    寻找重复的子树


    思路

    DFS+哈希表

    将每一棵子树都序列化称一个字符串,并保证相同的子树会被序列化成相同的子串、不同的子树会被序列化成不同的子串。只要使用一个哈希表存储所有子树的序列化结果,如果某个结果出现超过一次,就能发现一类重复子树。
    序列化二叉树的方法可以使用层次遍历,也可以使用递归进行序列化。这里使用深度优先搜索的方法递归序列化二叉树并存入哈希表,遍历时遇到重复的子树序列化结果就可以加入结果数组中。

    Python实现
    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class Solution:
        def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]:
            def dfs(node):
                if not node:
                    return ""
                serial = "".join([str(node.val), "(", dfs(node.left), ")(", dfs(node.right), ")"])
                if (tree := seen.get(serial, None)):
                    repeat.add(tree)
                else:
                    seen[serial] = node
                return serial
    
            seen = dict()
            repeat = set()
            dfs(root)
            return list(repeat)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    Java实现
    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
    
        Map<String, TreeNode> seen = new HashMap<>();
        Set<TreeNode> repeat = new HashSet<>();
    
        public String dfs(TreeNode node) {
            if (node == null) {
                return "";
            }
            StringBuilder sb = new StringBuilder();
            sb.append(node.val);
            sb.append("(");
            sb.append(dfs(node.left));
            sb.append(")(");
            sb.append(dfs(node.right));
            sb.append(")");
            String serial = sb.toString();
            if (seen.containsKey(serial)) {
                repeat.add(seen.get(serial));
            } else {
                seen.put(serial, node);
            }
            return serial;
        }
    
        public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
            dfs(root);
            return new ArrayList<TreeNode>(repeat);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    C++实现
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    private:
        unordered_map<string, TreeNode*> seen;
        unordered_set<TreeNode*> repeat;
    
    public:
        string dfs(TreeNode* node) {
            if (!node) {
                return "";
            }
            string serial = to_string(node->val) + "(" + dfs(node->left) + ")(" + dfs(node->right) + ")";
            if (auto tree = seen.find(serial); tree != seen.end()) {
                repeat.insert(tree->second);
            } else {
                seen[serial] = node;
            }
            return serial;
        }
    
        vector<TreeNode*> findDuplicateSubtrees(TreeNode* root) {
            dfs(root);
            return {repeat.begin(), repeat.end()};
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    Autoware中的点云3D聚类算法,保姆级算法阅读注释,一看就懂,非常详细!
    知识库系统都有哪些?知识库系统功能和介绍
    Docker Desktop Windows 无法启动
    安全队列和曲线拟合
    【2023研电赛】商业计划书命题:基于三维视觉感知的可重构智能表面通信设计
    【字符串函数内功修炼】strlen + strstr + strtok + strerror(三)
    深挖Cerebras:世界上最大AI芯片的架构设计
    港陆证券:日线9连阴意味着什么?
    linux内核中内存耗尽OOM killer
    opencv官方案例目录
  • 原文地址:https://blog.csdn.net/wcy1034036507/article/details/126710034