[LeetCode] 652. Find Duplicate Subtrees

45 篇文章 0 订阅

原题链接:https://leetcode.com/problems/find-duplicate-subtrees/

1. 题目介绍

Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node of any one of them.

Two trees are duplicate if they have the same structure with same node values.
给出一个二叉树,返回所有重复的子树。对于每一种重复的子树,你只需要返回一个该类子树的根节点即可。
什么样的两个子树是重复的呢?结构和节点的value值都相同的子树就是相同的子树。

Example 1:
在这里插入图片描述
The following are two duplicate subtrees:
上图中有两个重复的子树:
在这里插入图片描述

在这里插入图片描述
Therefore, you need to return above trees’ root in the form of a list.
因此,你需要返回以上子树的根节点。这些根节点需要存放在一个list里面。

2. 解题思路

为每棵树设置标识字符串

这个题的难点在于,如何判断两个子树是否是相同的?
最简单粗暴的方法就是同时遍历两棵树,如果遇到不同的结构或者节点,就认定两棵树是不同的。不过这种方法的开销太大了。

一种更聪明的方法是,找一种能够唯一表示子树的标识,比较两个子树的标识就能判断它们是否相等。随后将每个子树的标识都放入一个数组或者集合里面。每次分析一个新的子树时,首先计算出该子树对应的标识,然后去已有的标识集合中寻找,如果集合里面已经有了该标识,则说明该子树重复出现,如果没有,则将新的子树标识添加到集合里面去。

这种方法和 LeetCode本题的Solution中给出的两种方法是同样的思路,有兴趣的读者可以直接去看 https://leetcode.com/problems/find-duplicate-subtrees/solution/

什么样的标识可以唯一表示一棵子树?
答案有很多,其中一个比较好的方法是字符串。

比如题目中给的例子:
在这里插入图片描述
按照深度优先搜索的方法转化成字符串就是
124XXX324XXX4XX
其中X代表着子树为空的情况。

使用字符串唯一表示一棵树还有一个好处,就是当计算出子树的字符串后,根节点的字符串只需要将子树的字符串和自己的值进行拼接就可以计算出来了。
比如我知道了左子树的字符串是 24XXX,右子树是324XXX4XX,根节点是1
那么该树的全部字符串就是
1 + 24XXX + 324XXX4XX = 124XXX324XXX4XX

具体实现可参考下列代码:

/**
 * 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) {
        Map<String , Integer> map = new HashMap<>();
        List<TreeNode> ans = new ArrayList<>();
        TreeIdentifer(root , map , ans);
        return ans;
    }
    public String TreeIdentifer(TreeNode root , Map<String , Integer> map, List<TreeNode> ans){
    	if (root == null) {
    		return "X";
    	}
    	String thisTree = root.val + TreeIdentifer(root.left,map,ans) + TreeIdentifer(root.right,map,ans);
        map.put(thisTree, map.getOrDefault(thisTree,0) + 1);
        //map.getOrDefault(thisTree,0)意思就是当map中有thisTree这个key时,就使用这个key对应的value值,如果没有就使用0
        if(map.get(thisTree) == 2){
            ans.add(root);
        }
    	return thisTree;
    }
}

3. 参考链接

https://leetcode.com/problems/find-duplicate-subtrees/solution/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值