【发布时间】:2011-06-10 17:39:14
【问题描述】:
一个月前,我接受了一些谷歌 PTO 成员的采访。 其中一个问题是: js中递归反转字符串,用大O符号解释运行时间
这是我的解决方案:
function invert(s){
return (s.length > 1) ? s.charAt(s.length-1)+invert(s.substring(0,s.length-1)) : s;
}
我觉得很简单。
关于 big-o 符号,我很快回答了 O(n),因为运行时间线性地取决于输入。 - 沉默 - 然后,他问我,如果你通过迭代来实现,在运行时间方面有什么区别?
我回答说,有时编译器将递归“翻译”成迭代(一些编程语言课程记忆),因此在这种情况下迭代和递归没有区别。顺便说一句,由于我对这个特定问题没有任何反馈,而且面试官没有回答“好的”或“不”,我想知道你是否同意我的观点,或者你是否可以解释一下是否存在差异2种实现。
非常感谢和问候!
【问题讨论】:
-
我不确定,但递归中可能存在调用堆栈生成开销,这不会是循环中的。
-
顺便说一句,我会存储 s.length 而不是访问它 3 次,但也许不需要优化......(对不起,我总是过早地优化,这是我的许多错误之一)
-
@Martin:调用堆栈生成应该是非常很小的开销。无论如何,这里的代码递归 n 次,它的计算复杂度与迭代 n 次的循环相同。
-
@Martin @Juliet:谢谢,所以.. 你认为(除了可以存储的长度)计算复杂度不会从递归到迭代吗?
-
我绝对不是编译器/解释器专家,所以我只能根据我自 1997 年以来的 javascript 编码经验(服务器端、netscape faststrack 服务器)给你一些思考,不要问;)。如果您从一开始就知道要经历的迭代次数,迭代总是比递归快。在一个实际需要投入生产的项目中,我自己永远不会通过递归来实现字符串反转。也就是说,我发现它是一个优雅的解决方案:)
标签: javascript recursion iteration big-o