【发布时间】:2015-09-27 00:21:59
【问题描述】:
这个的时间和空间复杂度是多少:
def isPalindrome[A](x: Seq[A]): Boolean = x match {
case h +: middle :+ t => h == t && isPalindrome(middle)
case _ => true
}
是否依赖于Seq的实现?既然IndexedSeq 应该有O(1) 尾部与O(n) 对应LinearSeqs?空间复杂度是O(n)是因为递归调用堆栈还是Scala自动进行尾调用优化?
import scala.annotation.tailrec
@tailrec def isPalindrome[A](x: Seq[A]): Boolean = x match {
case h +: middle :+ t => h == t && isPalindrome(middle)
case _ => true
}
【问题讨论】:
-
很确定复杂性取决于实现。至于@tailrec,它用于强制执行尾递归(即,当注释但不是尾递归时抛出编译器错误)尾递归函数会自动优化。 Scala 没有完整的尾调用优化。
-
根据scala-lang.org/api/2.11.5/… scala List“有 O(1) prepend 和 head/tail access”关于时间性能,而 tail 的空间成本没有,我认为 head 也是如此,尽管没有说明. docs.scala-lang.org/overviews/collections/… 有一个收集时间性能特征表,显示 ArraySeq 的时间性能与头部的 List 相同,但尾部的 seq 长度为线性。
-
有没有我可以保留相同的代码并让它成为 O(n) 时间和 O(1) 空间?
标签: scala tail-recursion tail extractor unapply