我遇到了naive solution来检查二叉树是否是另一个二叉树的子树的问题:
给定两个二叉树,检查第一棵树是否是第二棵树的子树。树T的子树是由S中的节点及其在T中的所有后代组成的树S.对应于根节点的子树是整个树;与任何其他节点对应的子树称为适当的子树。
例如,在以下情况中,树S是树T的子树:
Tree 2
10
/ \
4 6
\
30
Tree 1
26
/ \
10 3
/ \ \
4 6 3
\
30
解决方案是以预购方式遍历树T.对于遍历中的每个访问节点,查看以此节点为根的子树是否与S相同。
在帖子中说,算法在最坏的情况下具有n ^ 2或O(m * n)的运行时间,其中m和n是所涉及的两个树的大小。
这里的混淆点是,如果我们同时遍历两棵树,在最坏的情况下,你似乎只需要通过较大的树中的所有节点递归来找到子树。那么这个版本的算法(不是this one)如何具有二次运行时间?
答案 0 :(得分:2)
好吧,基本上在isSubTree()
函数中,你只遍历T
树(主要树,而不是子树)。您对S
不执行任何操作,因此在最坏的情况下,将对T
中的每个节点执行此函数。然而(在最坏的情况下)每次执行时,它将检查areIdentical(T, S)
是否在最坏的情况下必须完全遍历给定的一个树(直到其中一个为零)。
传递给areIdentical()
函数的树明显越来越小,但在这种情况下,如果涉及时间复杂度则无关紧要。无论哪种方式,这都会为您提供O(n^2)
或O(n*m)
(其中n
,m
- 这些树中的节点数量。)
答案 1 :(得分:0)
为了合理地解决问题,将两棵树弄平。使用Lisp表示法, 我们得到
(10 (4(30) (6))
和
(26 (10 (4(30) (6)) (3 (3))
因此子树是父节点的子串。使用strstr我们可以 通常在O(N)时间内完成,可能需要更长的时间 如果我们有很多很多附近的子树。您可以使用后缀 如果你需要进行大量搜索并将其降低到O(M) 时间,其中M是子树的大小。
但实际上运行时并没有改善。它的算法相同, 例如,如果所有的树都会有N M行为 具有相同的节点ID和结构,除了最右边 查询子树的子节点。它只是操作 变得更快。