algorithm - 一棵树是另一棵树的子树吗?

标签 algorithm

来自 Lakmann :查找一棵树是否是另一棵树的子树: 作者说解决方案(转载如下)是 O(log(n) + log(m)) 内存,其中 n 和 m 是每棵树各自的节点数。我不明白为什么会这样。有什么指点吗?

boolean containsTree(TreeNode t1, TreeNode t2){
    if (t2 == null){
        return true;
    }
    return subTree(t1, t2);
}

boolean subTree(TreeNode r1, TreeNode r2){
    if (r1 == null){
        return false;
    }
    if (r1.data == r2.data){
        if (matchTree(r1, r2)){
            return true;
        }
    }
    return (subTree(r1.left, r2) || subTree(r1.right, r2));
}

boolean matchTree(TreeNode r1, TreeNode r2){
    if (r2 == null && r1 == null){
        return true;
    }
    if (r1 == null || r2 == null){
        return false;
    }

    if (r1.data != r2.data){
        return false;
    }

    return (matchTree(r1.left, r2.left) && matchTree(r1.right, r2.right)); 
}

最佳答案

请考虑这个具体的例子:

t1

            1
           /
          1
         /
        1
       /
      1
     /
    1
   /
  1

t2

    1
   / \
  1   1

现在检查 t2 是否包含在 t1 中。

毫无疑问,matchTree将在最后一步失败,t1 将遍历整棵树以发现它不包含。

因此,在退化树中,这是最坏的情况,复杂度为 O(mn)。

更新:

如果两棵树是平衡的,但没有排序,唯一可以优化的是,我们知道当 t1 的子树比 t2 短时我们可以停止,即 log(n) < log(m) ,所以复杂度可以优化为

O(2^(log(n)-log(m))*m) = O(n/m*m) = O(n)

更新2:

如果已排序且没有重复元素,则可以在O(log(n)) 中的t1 中找到t2 的根。 (如果存在),需要进行一次树遍历,即O(m) .所以它应该总结为 O(log(n) + m) .

关于algorithm - 一棵树是另一棵树的子树吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29019195/

相关文章:

algorithm - 向用户建议标签列表的算法

java - 将 list<string[]> 的每个元素彼此相交

java - 从平面列表生成嵌套列表(树)

performance - 为什么 float 除法很慢?

javascript - 组合数组删除重复项的最有效方法

c++ - 在 C/C++ 中快速显示波形

algorithm - 将文本消息拆分为 30 个字符的 block ,限制为后缀 (k/n)

algorithm - 如何将 Ford-Fulkerson 算法应用于图形以找到流量网络中的最大流量?

javascript - 有没有办法在应用 css 变换矩阵之前计算元素的结束位置?

Python 拓扑排序使用列表指示边