利用二叉树求解表达式的值_「力扣题型总结」匹配类二叉树

38ad4af59bc73715a145bd11fb1da901.png

匹配类二叉树可以使用一种套路相对固定的递归函数,在周赛中和每日一题中多次出现,而第一次见到不太容易写出正确的递归解法,因此我们来总结一下。(注:不要太纠结于名字,因为名字是我自己起的......)

这类题目与字符串匹配有些神似,求解过程大致分为两步:

  • 先将根节点匹配;
  • 根节点匹配后,对子树进行匹配。

而参与匹配的二叉树可以是一棵,与自身匹配;也可以是两棵,即互相匹配。

比如每日一题的「101. 对称二叉树」就是两棵树之间的匹配问题。为了更具一般性,我们先来看「面试题 04.10. 检查子树」这道题。

面试题 04.10. 检查子树

这道题的题意是这样的:输入两棵二叉树 AB,判断 B 是不是 A 的子结构,且约定空树不是任意一个树的子结构。

2205ccda8a8a52a6e9dac86f8f99d266.png

比如上面这个例子,我们发现 BA 的子结构,因为它们的结构相同,且节点值相等。

求解思路可以分解为以下两步:

  1. 匹配根节点:首先在 A 中找到与 B 的根节点匹配的节点 C
  2. 匹配其他节点:验证 C 的子树与 B 的子树是否匹配。

最终代码如下:

3f0a2476f9a8002416d9a893afaed278.png

代码中主要涉及 主函数和 dfs 函数 两个部分。与以上思路对应,主函数对应根节点的匹配,dfs 函数对应匹配其他节点。

dfs 函数

dfs 函数将注意力集中在了根节点已经匹配的情况。当从根节点同时开始向下遍历时,我们进行以下判断:

  1. 如果 AB 同时遍历到了 null,说明匹配成功,返回 True(case 1 红色虚线框);
  2. 如果 AB 提前遍历到了 null,一棵树匹配完了,另一棵却没有,说明子树的结构是不同的,则匹配失败,返回 False(case 2 红色虚线框)。

d663a29cbd261db36386fb6fba7c064b.png

以上是“基本情况”,在到达基本情况之前,我们需要判断根节点的值、左子树(调用递归)和右子树(调用递归)是否匹配。

于是就有了代码中的 dfs 函数形式:

a7af55e7f732ef0eee7174970912b054.png

主函数

现在将视野放远来看,主函数则解决了如何确定 A 的哪个节点是 B 的根节点

如果 A 的当前节点值与 B 的根节点值相同,我们调用 dfs 函数判断子树是否也相同;如果不同,我们就递归调用主函数来寻找 A 的哪个节点与 B 的根节点匹配。

所以,主函数会写成这样:

596356bf80e8eba52e6b681296768dba.png

当然,主函数还经常需要判断以下边界条件,比如如果 A 为空,则肯定不匹配,返回 False

总结

熟悉了以上的思路之后,力扣很多类似的题目都可以使用题目中的代码解决。

这些题目中,可能会有自身和自身做匹配的,比如每日一题「101. 对称二叉树」,将自身看作两棵树,用左子树和右子树镜像比较;

可能会将另一棵树变成一个链表,比如「1367. 二叉树中的列表」,仍然是先将链表头部与二叉树的某个节点匹配,再验证后续是否匹配;

也可能像「面试题26. 树的子结构」这样,前面的例题很像,不同的是 B 属于 A 的一部分也可以,没必要一直匹配到叶子节点;

还有与例题相同思路的「572. 另一个树的子树」

......


算法与技术面试​zhuanlan.zhihu.com
599e45270d7c23cd8852db8cc6d1122d.png
腐烂的橘子:旋转数组的通用解决办法​zhuanlan.zhihu.com
24e769bfc5ef87d5d8ab8e2e1f22debb.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值