寻找重复子树
给定一棵二叉树 root,返回所有重复的子树。
对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。
如果两棵树具有相同的结构和相同的结点值,则它们是重复的。
示例 1:
输入:root = [1,2,3,4,null,2,4,null,null,4] 输出:[[2,4],[4]]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-duplicate-subtrees
如果你想知道以自己为根的子树是不是重复的,是否应该被加入结果列表中,你需要知道什么信息?
你需要知道以下两点:
1、以我为根的这棵二叉树(子树)长啥样?
2、以其他节点为根的子树都长啥样?
那我们一个一个来解决,先来思考,我如何才能知道以自己为根的二叉树长啥样?
其实看到这个问题,就可以判断本题要使用「后序遍历」框架来解决:
String traverse(TreeNode root) {
// 对于空节点,可以用一个特殊字符表示
if (root == null) {
return "#";
}
// 将左右子树序列化成字符串
String left = traverse(root.left);
String right = traverse(root.right);
/* 后序遍历代码位置 */
// 左右子树加上自己,就是以自己为根的二叉树序列化结果
String subTree = left + "," + right + "," + root.val;
return subTree;
}
将二叉树序列化可解决第一个问题
借助一个外部数据结构,让每个节点把自己子树的序列化结果存进去,这样,对于每个节点,不就可以知道有没有其他节点的子树和自己重复了么?
初步思路可以使用HashMap
记录子树,注意要处理出现多次的重复子树
总体实现javascript代码:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {TreeNode[]}
*/
var findDuplicateSubtrees = function(root) {
let map=new Map();
let res=[];
var traverse = function(root){//后序遍历将二叉树序列化,将每个结点形成的树存进map中
if(!root) return '#';
let leftnode=traverse(root.left);
let rightnode=traverse(root.right);
let subTree=leftnode + ','+rightnode+','+root.val;//判断每个root结点对应的序列化
if(!map.has(subTree)) map.set(subTree,1);//第一次
let count=map.get(subTree);//获取出现的次数
if(count===2) {//确保多次重复的root只加入结果集一次
res.push(root);
}
map.set(subTree,count+1);//记录出现的次数
return subTree;
}
traverse(root);
return res;
};
还可以用深度遍历+二叉树序列化实现
参考链接:
https://mp.weixin.qq.com/s/LJbpo49qppIeRs-FbgjsSQ
阅读剩余
版权声明:
作者:chun
链接:https://chun53.top/1066.html
文章版权归作者所有,未经允许请勿转载。
THE END