寻找重复的子树 Find Duplicate Subtrees
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的更多相关文章
- LeetCode 652: 寻找重复的子树 Find Duplicate Subtrees
LeetCode 652: 寻找重复的子树 Find Duplicate Subtrees 题目: 给定一棵二叉树,返回所有重复的子树.对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可. 两 ...
- [Swift]LeetCode652. 寻找重复的子树 | Find Duplicate Subtrees
Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only ne ...
- Leetcode 652.寻找重复的子树
寻找重复的子树 给定一棵二叉树,返回所有重复的子树.对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可. 两棵树重复是指它们具有相同的结构以及相同的结点值. 下面是两个重复的子树: 因此,你需 ...
- Java实现 LeetCode 652 寻找重复的子树(两个map的DFS)
652. 寻找重复的子树 给定一棵二叉树,返回所有重复的子树.对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可. 两棵树重复是指它们具有相同的结构以及相同的结点值. 示例 1: 1 / \ ...
- [LeetCode] Find Duplicate Subtrees 寻找重复树
Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only ne ...
- 652. Find Duplicate Subtrees找出重复的子树
[抄题]: 就是出现了多次的子树,可以只包括一个点. Given a binary tree, return all duplicate subtrees. For each kind of dupl ...
- 【LeetCode】652. Find Duplicate Subtrees 解题报告(Python)
[LeetCode]652. Find Duplicate Subtrees 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博 ...
- LeetCode——Find Duplicate Subtrees
Question Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, yo ...
- Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number)
Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number) 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 ...
随机推荐
- tfs项目解绑及svn上传
1.tfs解绑 file--源代码管理——tfs解绑 2.svn将本地的文件夹上传到server 右击--import--url--新建文件夹
- Mysql闭包表之关于国家区域的一个实践
在电商系统中,我们总是会遇到一些树形结构数据的存储需求.如地理区域.位置信息存储,地理信息按照层级划分,会分为很多层级,就拿中国的行政区域划分为例,简单的省-市-县-镇-村就要五个级别.如果系统涉及到 ...
- 5select的运用
四.select的运用 --汇总函数 max()最大值,min()最小值,avg()平均值select max(age),min(age),avg(age) from tablename; --算出表 ...
- java多线程----线程池源码分析
http://www.cnblogs.com/skywang12345/p/3509954.html 线程池示例 在分析线程池之前,先看一个简单的线程池示例. 1 import java.util.c ...
- 函数指针(pointer to function)——qsort函数应用实例
一,举例应用 在ACM比赛中常使用 stdlib.h 中自带的 qsort 函数,是教科书式的函数指针应用示范. #include <stdio.h> #include <stdli ...
- 20145118《Java程序设计》 第8周学习总结
20145118<Java程序设计> 第8周学习总结 教材学习内容总结 1.Java SE提供了日志API,可以基于标准调用,用于记录.java.util.logging包提供了日志功能相 ...
- 20145317《网络对抗》Exp4 恶意代码分析
20145317<网络对抗>Exp4 恶意代码分析 一.基础问题回答 (1)总结一下监控一个系统通常需要监控什么.用什么来监控. 通常监控以下几项信息: 注册表信息的增删添改 系统上各类程 ...
- 20145322 Exp5 Adobe阅读器漏洞攻击
20145322 Exp5 Adobe阅读器漏洞攻击 实验过程 IP:kali:192.168.1.102 windowsxp :192.168.1.119 msfconsole进入控制台 使用命令为 ...
- 关于python环境的一些安装设置
操作系统Redhat Linux,自带python2.6.Python程序的运行其实相当简单,只需在操作系统中安装并配置好python环境即可,和运行java需要配置jre一样(哪里简单,真简单就不会 ...
- POJ 1751 Highways(最小生成树&Prim)题解
思路: 一开始用Kruskal超时了,因为这是一个稠密图,边的数量最惨可能N^2,改用Prim. Prim是这样的,先选一个点(这里选1)作为集合A的起始元素,然后其他点为集合B的元素,我们要做的就是 ...