算法小抄学习笔记 — 4.二叉树递归思想训练(三)

1 如何判断使用先序、中序还是后序遍历

仔细思考一个二叉树节点需要做什么的前提条件,然后使用什么遍历就清楚起来了。

例如:

1.1 226. 翻转二叉树

1.1.1 题目

翻转一棵二叉树。

示例:

输入:

     4
   /   \
  2     7
 / \   / \
1   3 6   9

输出:

     4
   /   \
  7     2
 / \   / \
9   6 3   1

要翻转以根节点为树时,需要的前提条件是

  • 其左子树内部已经翻转。
  • 其右子树内部已经翻转。

所以就很清楚知道这题需要后序遍历,然后只需要

  • 交换左右子树



2 题目

2.1 652. 寻找重复的子树

2.1.1 题目

给定一棵二叉树,返回所有重复的子树。对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。

两棵树重复是指它们具有相同的结构以及相同的结点值。

示例 1:

        1
       / \
      2   3
     /   / \
    4   2   4
       /
      4

下面是两个重复的子树:

      2
     /
    4

    4

2.1.2 思路

先思考使用什么遍历,所以需要知道根节点做什么的前提条件,以节点3为例,要想知道3节点为根的树是否重复,需要知道

  • 其他节点的子树长什么样。
  • 以我为根的子树长啥样。

所以很明显只能使用后序遍历

这样就需要判断二叉树的唯一性,那怎样判断一棵二叉树是否唯一呢? 可以用前面说到的二叉树序列化来实现,将一二叉树转换为相应的字符序列,然后遍历途中,依次判断序列是否重复即可。

2.1.3 实现

class Solution {
    Map<String, Integer> repeat_counts = new HashMap<>();
    List<TreeNode> repeat_nodes = new ArrayList<>();

    public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
        travase(root);
        return repeat_nodes;
    }

    String travase(TreeNode root) {
        if (root == null) {
            return "#";
        }

        String left = travase(root.left);
        String right = travase(root.right);

        /* ---- 后序遍历代码 ---- */
        String res = left + "," + right + "," + root.val;
        int freq = repeat_counts.getOrDefault(res, 0);
        if (freq == 1) {
            repeat_nodes.add(root);
        }
        repeat_counts.put(res, freq + 1);
        /* --------------------- */

        return res;
    }
}



3 参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值