判断t1树是否包含t2树全部的拓扑结构
《程序员代码面试指南》第41题 P142 难度:士★☆☆☆
该题难度为士,算简单题,虽然我还想了好一会,敲了好一会,debug了好一会,然后做的还有一点小问题o(╥﹏╥)o(不得不佩服左神和力扣上的一些大神,代码能力太强了,写的代码真的很精致)
题解的思路是:如果t1中某棵子树头节点的值与t2头节点的值一样,则从这两个头节点开始匹配,匹配的每一步都让t1上的节点跟着t2上的节点的先序遍历移动。每移动一步,都检查t1的当前节点是否与t2当前节点的值一样。匹配完毕则返回true。如果匹配的过程中发现有不匹配的情况,则直接返回false。然后再去寻找t1的下一棵子树。t1的每棵子树都有可能匹配出t2,所以都要检查一遍。
我自己的思路错在以下的结构检测出false,我觉得根本原因还是在于我没有用2个递归来实现,代码写的非常混乱。(画的丑不要介意)
题解代码如下:
public boolean contains(Node t1, Node t2) {
if (t2 == null) {
return true;
}
if (t1 == null) {
return false;
}
return check(t1, t2) || contains(t1.left, t2) || contains(t1.right, t2);
}
public boolean check(Node h, Node t2) {
if (t2 == null) {
return true;
}
if (h == null || h.value != t2.value) {
return false;
}
return check(h.left, t2.left) && check(h.right, t2.right);
}
第一层递归是逐个判断t1各个节点作为头节点的情况下是否包含t2的拓扑结构。注意return的||,也有短路的意思,即有一个为true了,其它的都不用判断了,整个t1必定包含t2的拓扑结构了。
第二层递归就是以从第一层传过来的t1的某个节点作为头节点,和t2的头节点同时开始做先序遍历,来判断每个值是否匹配。同样,注意&&的短路,一旦有不匹配的值,则其它也都不用判断了,最后整个就返回false了。
要多学习这种递归的写法,太完美了(⊙o⊙)…