寻找重复的子树 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 和 ...
随机推荐
- Sa身份登陆SQL SERVER失败的解决方案
经常使用windows身份登陆,久而久之,基本不动怎么用SQL SERVER身份验证登陆,所以趁着有空,就解决一下一些问题~~ 解决方案: 第一步:打开SSMS,先使用windows身份登陆,右击服 ...
- Linux服务器---apache支持cgi
Apache支持cgi 1.打开Apache配置文件httpd.conf,搜索“cgi”,找到下面的一段,去掉“addhandler”前面的“#“,这样就开启了Apache的cgi功能 [root@ ...
- JProfiler8 远程监控tomcat配置过程
1. 阅读人群 1.熟悉liunx服务器,起码知道liunx常见的命令 2.熟悉tomcat容器,起码知道怎么tomcat的启动以及停止 3.熟悉java编程语言,JProfiler8是专门监控jav ...
- Struts2快速后台验证 使用
为了和前台基于JavaScript的开源验证框架RapidValidation使用统一的验证规则, 最大限度的减少重复的后台验证代码, 使用方式简便, 扩展方便. https://blog.csdn. ...
- CPU负载过高异常排查实践与总结
昨天下午突然收到运维邮件报警,显示数据平台服务器cpu利用率达到了98.94%,而且最近一段时间一直持续在70%以上,看起来像是硬件资源到瓶颈需要扩容了,但仔细思考就会发现咱们的业务系统并不是一个高并 ...
- CentOS安装mysql并配置远程访问
最近上班挺无聊,每天就是不停的重启重启重启,然后抓log.于是有事儿没事儿的看卡闲书,搞搞其他事情. 但是,公司笔记本装太多乱其八糟的东西也还是不太好. 于是,想到了我那个当VPN server的VP ...
- Java系列笔记(5) - 线程
我想关注这个系列博客的粉丝们都应该已经发现了,我一定是个懒虫,在这里向大家道歉了.这个系列的博客是在我工作之余写的,经常几天才写一小节,不过本着宁缺毋滥的精神,所有写的东西都是比较精炼的.这篇文章是本 ...
- bzoj1651 / P2859 [USACO06FEB]摊位预订Stall Reservations
P2859 [USACO06FEB]摊位预订Stall Reservations 维护一个按右端点从小到大的优先队列 蓝后把数据按左端点从小到大排序,顺序枚举. 每次把比右端点比枚举线段左端点小的数据 ...
- 20145310 《网络对抗》 MSF基础应用
实验要求 掌握metasploit的基本应用方式,掌握常用的三种攻击方式的思路. 一个主动攻击,如ms08_067; 一个针对浏览器的攻击,如ms11_050: 一个针对客户端的攻击,如Adobe 成 ...
- C#中基于流的XML文件操作笔记
System.Xml.XmlReader和System.Xml.XmlWriters是两个抽象类,XmlReader提供了对于XML数据的快速,非缓存,只进模式的读取器,XmlWriter表示一个编写 ...