【发布时间】:2014-04-18 14:06:05
【问题描述】:
我昨天接受了一个采访,涉及一个非常基本的树数据结构:
t ::= int | (t * t)
其中一个 tTree 是一个整数(叶)或两个 t,它们代表左右子树。这意味着树将仅在叶级别具有值。
示例树可能如下所示:
t
/ \
t t
/ \ / \
1 2 3 4
任务是编写一个函数equal(t, t) => bool,它接受两个 tTree 并确定它们是否相等,非常简单。
我写了非常标准的代码,结果是这样的(下面是伪代码):
fun equal(a, b) {
if a == b { // same memory address
return true
}
if !a || !b {
return false
}
// both leaves
if isLeaf(a) && isLeaf(b) {
return a == b
}
// both tTrees
if isTree(a) && isTree(b) {
return equal(a->leftTree, b->leftTree)
&& equal(a->rightTree, b->rightTree)
}
// otherwise
return false
}
当被要求给出时间和空间复杂度时,我很快回答:
O(n) time
O(1) space
我的面试官声称他们可以创建一棵树,这样这个相等的函数就可以在O(2^n) 指数时间内运行。鉴于上述算法,我没有(现在仍然没有)看到这是怎么可能的。我看到该函数递归调用自身两次,但是每次调用的输入大小都减半,对吗?因为您只是在并行检查各个子树。
对此的任何想法或意见都会非常有帮助。
【问题讨论】:
-
出于好奇,他们为什么要编写一个极慢版本的函数?
-
?我不确定我是否遵循。他们不希望我创建一个可以在指数时间内运行的算法,他们说我的上述算法在某些树的指数时间内运行。我不明白。
-
哦,我明白了。然后误解了这些问题。
-
你的n是叶子数,他们的n是分支层数
-
我不明白,因为树在定义上是平衡的,所以他们可以改变的唯一变量是级别数。没有太多要“构建”的东西。据我所知,这基本上等于列表比较。
标签: algorithm complexity-theory