2018-07-29 17:42:29

问题描述:

问题求解:

本题是要求寻找一棵树中的重复子树,问题的难点在于如何在遍历的时候对之前遍历过的子树进行描述和保存。

这里就需要使用之前使用过的二叉树序列化的手法,将遍历到的二叉树进行序列化表达,我们知道序列化的二叉树可以唯一的表示一棵二叉树,并可以用来反序列化。

想到这里其实问题就已经解决了一大半了, 我们只需要在遍历的过程中将每次的序列化结果保存到一个HashMap中,并对其进行计数,如果重复出现了,那么将当前的节点添加到res中即可。

    public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
List<TreeNode> res = new ArrayList<>();
Map<String, Integer> map = new HashMap<>();
helper(root, map, res);
return res;
} private String helper(TreeNode root, Map<String, Integer> map, List<TreeNode> res) {
if (root == null) return "#";
String str = root.val + "," + helper(root.left, map, res) + "," + helper(root.right, map, res);
if (map.containsKey(str)) {
if (map.get(str) == 1) res.add(root);
map.put(str, map.get(str) + 1);
}
else map.put(str, 1);
return str;
}

算法改进:

上述的算法基本可以在O(n)的时间复杂度解决问题,但是其中的字符串拼接是非常耗时的,这里可以对这个部分做出一点改进。如果我们不用序列化结果来表征一个子树,用一个id值来表征的话,那么就可以规避掉字符串拼接的问题。

这里直接使用id的size来进行id的分配,值得注意的是由于已经给null分配了0,那么每次分配的大小应该是size + 1。

    public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
List<TreeNode> res = new ArrayList<>();
Map<Long, Integer> id = new HashMap<>();
Map<Integer, Integer> map = new HashMap<>();
helper(root, id, map, res);
return res;
} private Integer helper(TreeNode root, Map<Long, Integer> id, Map<Integer, Integer> map, List<TreeNode> res) {
if (root == null) return 0;
Long key = ((long) root.val << 32) | helper(root.left, id, map, res) << 16 | helper(root.right, id, map, res);
if (!id.containsKey(key))
id.put(key, id.size() + 1);
int curId = id.get(key);
if (map.containsKey(curId)) {
if (map.get(curId) == 1) res.add(root);
map.put(curId, map.get(curId) + 1);
}
else map.put(curId, 1);
return curId;
}

寻找重复的子树 Find Duplicate Subtrees的更多相关文章

  1. LeetCode 652: 寻找重复的子树 Find Duplicate Subtrees

    LeetCode 652: 寻找重复的子树 Find Duplicate Subtrees 题目: 给定一棵二叉树,返回所有重复的子树.对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可. 两 ...

  2. [Swift]LeetCode652. 寻找重复的子树 | Find Duplicate Subtrees

    Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only ne ...

  3. Leetcode 652.寻找重复的子树

    寻找重复的子树 给定一棵二叉树,返回所有重复的子树.对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可. 两棵树重复是指它们具有相同的结构以及相同的结点值. 下面是两个重复的子树: 因此,你需 ...

  4. Java实现 LeetCode 652 寻找重复的子树(两个map的DFS)

    652. 寻找重复的子树 给定一棵二叉树,返回所有重复的子树.对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可. 两棵树重复是指它们具有相同的结构以及相同的结点值. 示例 1: 1 / \ ...

  5. [LeetCode] Find Duplicate Subtrees 寻找重复树

    Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only ne ...

  6. 652. Find Duplicate Subtrees找出重复的子树

    [抄题]: 就是出现了多次的子树,可以只包括一个点. Given a binary tree, return all duplicate subtrees. For each kind of dupl ...

  7. 【LeetCode】652. Find Duplicate Subtrees 解题报告(Python)

    [LeetCode]652. Find Duplicate Subtrees 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博 ...

  8. LeetCode——Find Duplicate Subtrees

    Question Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, yo ...

  9. Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number)

    Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number) 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和  ...

随机推荐

  1. 强大的chrome(1)以acfun为例抓取视频

    chrome很强大,很强大,很强大. 想要了解他的强大呢,就先要掌握一些基本的chrome命令. 1. chrome://flags   可用来启用或者关闭某些chrome的体验特性   2. chr ...

  2. Python: Pycharm简单介绍

    1. Pycharm是什么?                                                                                       ...

  3. Linux基础命令---gzip

    gzip gzip通过Lempel-ziv算法来压缩文件,压缩的时候保留每个文件的所有者.权限.修改时间.对于符号链接,gzip将会忽略它. 如果压缩的文件名对其文件系统来说太长,则gzip将截断它. ...

  4. ACM题目————中位数

    题目描述 长为L的升序序列S,S[L / 2]为其中位数. 给出两个等长升序序列S1和S2,求两序列合并并排序后的中位数. 输入 多组数据,每组第一行为n,表示两个等长升序序列的长度. 接下来n行为升 ...

  5. loj10009 P1717 钓鱼

    P1717 钓鱼 贪心+优先队列 先枚举最后走到哪个湖,然后用优先队列跑一遍贪心即可 #include<iostream> #include<cstdio> #include& ...

  6. 20145220韩旭飞《网络对抗》Exp6 信息搜集与漏洞扫描

    20145220韩旭飞<网络对抗>Exp6 信息搜集与漏洞扫描 信息搜集 whois查询 以百度的网址为例,使用whois查询域名注册信息: 从上图中可以得到3R注册信息,包括注册人的名字 ...

  7. C++使用TinyXML

    参照一:http://qaohao.iteye.com/blog/496237 参照二:http://hi.baidu.com/lnylvoeegzcgnrr/item/af68fd9cde40fc1 ...

  8. JavaScript:正则表达式 全局

    关于正则表达式的 RegExp方法:test,exec, String 方法:match,search, 全局 g var str = "abababa"; var re = /a ...

  9. 蚂蚁感冒|2014年蓝桥杯B组题解析第八题-fishers

    蚂蚁感冒 长100厘米的细长直杆子上有n只蚂蚁.它们的头有的朝左,有的朝右. 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒. 当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行. 这些蚂蚁中,有1只蚂 ...

  10. 【第七章】 springboot + retrofit

    retrofit:一套RESTful架构的Android(Java)客户端实现. 好处: 基于注解 提供JSON to POJO,POJO to JSON,网络请求(POST,GET,PUT,DELE ...