【LeetCode算法学习笔记】二叉树 第三期

labuladong算法公众号学习笔记


根据题意,思考一个二叉树节点需要做什么,到底用什么遍历就清楚了
二叉树框架

void traverse(TreeNode root){
    //前序遍历
    traverse(root.left);
    //中序遍历
    traverse(root.right);
    //后序遍历
}

节点应该做什么

  • 以自己为根的二叉树(子树)是什么样子
  • 以其他节点为根的子树的样子

如何知道自己的子树

用后序遍历法,要先知道自己的左子树、右子树和根才行。
举例:二叉树有多少节点:

int count(TreeNode root){
    if(root == null) return 0;
    //先计算出左右子树有多少节点
    int left=count(root.left);
    int right=count(root.right);
    /*后序遍历代码*/
    int res=left+right+1;
    return res;
}

例:通过拼接字符串的方式把二叉树序列化

String traverse(TreeNode root){
    //空节点,可以用一个特殊字符表示
    if(root == null) return "#";
    String left = traverse(root.left);
    String right = traverse(root.right);
    /*后序遍历代码*/
    //左右子树加上自己,就是以自己为根的二叉树
    String subTree = left +" "+ right;
    return subTree;
}

知道别的树长什么样

可以借助一个外部数据结构,让每个节点把自己子树的序列化结果存进去,这样,对于每个节点,可以知道其他节点的子树和自己是否重复。
可以利用HashMap来额外记录每棵子树的出现次数:

//记录所有子数以及出现的次数
HashMap<String,Integer> memo = new HashMap<>();
//记录重复的子树根节点
LinkedList<TreeNode> res = new LinkedList<>();

/*主函数*/
List<TreeNode> findDuplicatedSubtree(TreeNode root){
    traverse(root);
    return res;
}
/*辅助函数*/
String traverse(TreeNode root){
    if(root == null) return "#";
    String left = traverse(root.left);
    String right = traverse(root.right);
    String subTree = left + " , " + right;
    int freq = memo.getOrDefault(subTree,0);
    //多次重复也只会被加入结果集一次
    if(freq == 1) res.add(root);
    //给子树对应的出现次数加1
    memo.put(subTree,freq+1);
    return subTree;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值