检查调整相同二叉树的时间复杂度

时间:2016-01-19 19:12:41

标签: algorithm data-structures binary-tree big-o time-complexity

我在网上法官遇到如下问题:

检查两个给定的二叉树是否相同。假设允许任意数量的调整。调整被定义为树中一个节点的子节点的交换。

enter image description here

我提出了以下接受的天真算法。

/**
 * @aaram a, b, the root of binary trees.
 * @return true if they are tweaked identical, or false.
 */
bool isTweakedIdentical(TreeNode* a, TreeNode* b) {
    if (!a || !b)
        return !a && !b;
    return a->val == b->val && 
    ((isTweakedIdentical(a->left, b->left) && isTweakedIdentical(a->right, b->right)) ||
    (isTweakedIdentical(a->left, b->right) && isTweakedIdentical(a->right, b->left)));
}

但是,我无法弄清楚我的解决方案的时间复杂性。任何人都可以教我如何分析它?我不确定最坏的情况何时发生。

2 个答案:

答案 0 :(得分:0)

这取决于你期望树的“二进制”。

如果构建的树往往更加线性链接,那么您的算法将倾向于线性执行O(N)(具有N个非尾调用递归,这可能导致堆栈溢出大树)。 / p>

如果您构建的树往往更加二进制,因为两个子节点的每个节点的树大小大致相等,那么您的算法将以对数方式执行对数​​ O(log2(N)) < / s> O(N^2)

最糟糕的情况是a在右侧是线性的,而b在左侧是线性的。您可以通过伪随机选择要检查的路径来改善您的平均情况,但是以每次调用函数调用rand()为代价。我不知道这是否值得花费,但这只是一个建议。

修改

考虑二叉树的这个例子:

       _1_
      /   \
    _2     3_
   / |     | \
  4  5     6  7
 /|  |\   /|  |\
8 9  A B C D  E F

       _1_
      /   \
    _3     2_
   / |     | \
  7  6     5  4
 /|  |\   /|  |\
F E  D C B A  9 8

这是heaps的两个例子。他们匹配,除了他们被镜像。这将需要对isTweakedIdentical()进行43次调用才能返回true。但这似乎是一个O(N)操作,考虑到每个节点平均3次调用(根除了)。我稍后会完成编辑。

答案 1 :(得分:0)

对于初学者来说,让我们假设你正在使用一个包含n个节点的完美二叉树。在每个级别,您最多触发四个递归调用,每个调用都到一个二进制树,其中包含(大致)n / 2个节点。你每次调用都在做O(1)工作,所以我们得到了递归关系

  

T(n)≤4T(n / 2)+ O(1)

使用主定理,我们处于a = 4,b = 2和d = 0的情况下,并且因为log b a = log 2 4 = 2且d = 0,在这种情况下,我们看到运行时为O(n 2 )。

这个上限的问题在于它并不紧张。特别是,查看所进行的递归调用的结构,如果不存在短路,我们只能获得四次递归调用。这将要求在两种情况中的每一种情况下的第一次调用返回true,而第二次分支返回false。我花了最后半个小时试图制作一个最坏情况的树,并证明它是一个最坏情况的树,但我有一点时间这样做。我怀疑答案介于O(n log 2 3 )之间,这是每个节点三次调用得到的结果,O(n 2 < / sup>),但我不确定。遗憾!