题目链接
啊这个题如果用暴力做法的话就是枚举s中的节点然后和t的根结点比较,找到后再进行两棵树的遍历去判断是否相等。如1所示,这样做的时间复杂度为O( |
s |
x |
t |
),空间复杂度为O(max{d_s, d_t}),d表示树的深度。 |
另外一种方法是在DFS序列上做串匹配。我们首先要了解一个小套路:一棵子树上的点在DFS序列(即先序遍历)中是连续的。了解了这个小套路之后,我们可以确定这个问题的方向就是:把s和t先转换成DFS序,然后看t的DFS序是否是s的DFS序的子串。这样做一定正确吗,其实不一定,假设s有两个节点,1是根,2是左孩子,而t也有两个节点,1也是根,但是2是右孩子。这样一来s和t的DFS序列相同可是t并不是s的子树。由此可见,“s的DFS序包含t的DFS序”是“t是s子树”的必要不充分条件,所以单纯这样做是不正确的。为了解决这个问题,我们引入两个空值lNull和rNull,当一个节点的左孩子或者右孩子为空时,就插入这两个空值,这样DFS序列就唯一对应一棵树。然后,在判断“s的DFS序包含t的DFS序”的时候,可以暴力匹配也可以使用KMP算法。该方法如2所示,其中搜索时用了KMP算法。这个算法的时间复杂度是O( |
s |
+ |
t |
),空间复杂度是O( |
s |
+ |
t |
)。 |
python:
C++: