zoukankan      html  css  js  c++  java
  • leetcode652

    Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node of any oneof them.
    Two trees are duplicate if they have the same structure with same node values.
    Example 1:
    1
    /
    2 3
    / /
    4 2 4
    /
    4
    The following are two duplicate subtrees:
    2
    /
    4 and 4
    Therefore, you need to return above trees' root in the form of a list.

    树的DFS。后序遍历。树的serialization。
    思路:要区分不同的subtrees,就规定一种序列化方法,序列化之后两者得到的答案一样就说明结构与值都是一样的。
    序列化方法:1.直接str。O(n)时间。根的val+左序列化后的+右序列化后的。2.str+编号。O(1)时间。我们规定比如“235466”字符串有一个唯一的int标号(可以通过map.size()快速生成不同编号),这样就把无限长的str压缩成一个integer大小了。这种方法要求后序遍历,从而保证左右的先都被编好号了。
    数据结构:Map<String, Integer> codes记录str到编号的转换(因为你整体都用编号生成str了,所以这里的str里包含的就是两个int+当前val,已经不会像原始情况下那么长了,此时可以说是O(1))Map<Integer, Integer> counts记录某个编号出现过多少次。

    细节:
    1.TreeNode加入ans的时间契机只在出现重复的第一次,count == 1的那次,之后不能重复加。
    2.root == null的情况返回-1即可,优雅处理。
    3.序列化做法时间复杂度O(n^2), 序列化+进一步编号时间复杂度O(n)。

    实现:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
            List<TreeNode> ans = new ArrayList<>();
            postOrder(root, new HashMap<>(), new HashMap<>(), ans);
            return ans;
        }
        
        private int postOrder(TreeNode root, Map<String, Integer> codes, Map<Integer, Integer> counts, List<TreeNode> res) {
            if (root == null) {
                return -1;
            }
            
            int left = postOrder(root.left, codes, counts, res);
            int right = postOrder(root.right, codes, counts, res);
            
            String str = root.val + "#" + left + "#" + right;
            int code;
            if (codes.containsKey(str)) {
                // find same code again, deal and update.
                code = codes.get(str);
                if (counts.get(code) == 1) {
                    res.add(root);
                }
                counts.put(code, counts.get(code) + 1);
            } else {
                // generate new code.
                code = codes.size();
                codes.put(str, code);
                counts.put(code, 1);
            }
            return code;
        }
    }
  • 相关阅读:
    虚拟机安装Linux方案和操作系统启动流程
    CentOS7防止root密码被破解
    子网划分和VLAN
    Python之包的相关
    禁止复制文本的代码 HTML
    asp.net中Session过期设置方法
    CSS+DIV问题!DIV的最小高度问题!
    设置COOKIE过期时间的方法
    网站常见问题及解决方法(div/css)
    ASP.NET中如何删除最近打开的项目和文件的记录
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/9666953.html
Copyright © 2011-2022 走看看