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;
}
}