【发布时间】:2013-07-22 04:26:43
【问题描述】:
所以,我有明显的蛮力算法,如下所示
int isSubtree (binTree *S, binTree *T)
{
if (S == NULL)
return 0;
return (isEqual (S,T) || isSubtree (S->left, T) || isSubtree (S->right, T));
}
int isEqual (binTree *S, bintree *T)
{
if (S==NULL && T==NULL)
return 1;
if (S==NULL || T==NULL)
return 0;
if (S->val == T->val)
return isEqual(S->left,T->left) && isEqual (S->right,T->right);
else
return 0;
}
但这是 O(n²) 的方法。
我有另一种方法,如下所示,是 O(n) 我们以中序方式遍历第一棵树并将其存储在一个数组中。然后我们遍历第二棵树并以有序的方式存储它。现在,如果第二个数组是第一个数组的子数组,我们继续并重复相同的过程来进行前序遍历。如果两个查询的结果都是 TRUE,则树是第一棵树的子树。否则,不。
谁能告诉我以下算法是否可行?
对于这个问题是否有更优化空间的解决方案?
注意:我需要两个数组,因为我存储了两个数组的遍历,有没有我可以只使用一个数组?就像我会存储其中一棵树的中序遍历,然后在遍历另一棵树时使用该数组检查子数组条件。 或者可能没有额外的空间但 O(n) 时间复杂度?
注意:子数组是指元素应该连续出现,即
{2,3,5} is a subarray of {1,2,3,5} but not a subarray of {1,2,3,4,5}
【问题讨论】:
-
您的蛮力算法的复杂度仅为 O(n)。你怎么说它是n^2个soln?
-
在每次递归中,您实际上是在删除一个节点。所以,它只是 O(n),这需要做 3 次。
-
@Karthikeyan:假设
S中的所有节点都持有1,而T中的所有节点都是1,除了最右边的一个孩子持有2。那么每个isEqual检查将遍历所有节点T,最后才发现不匹配。对S中的每个节点重复此操作。 -
知道了,对不起,我的错..
-
isEqual() 函数是 O(n),在最坏的情况下,我们遍历 isSubtree() 中的每个节点,我们会得到 O(n²) 的整体时间复杂度,不是吗?