What is the time and space complexity for this:
def isPalindrome[A](x: Seq[A]): Boolean = x match {
case h +: middle :+ t => h == t && isPalindrome(middle)
case _ => true
}
Does it depend on the implementation of Seq? Since IndexedSeq should have O(1) tail vs O(n) for LinearSeqs? Is the space complexity is O(n) because of the recursive call stack or does Scala does tail call optimization automatically?
import scala.annotation.tailrec
@tailrec def isPalindrome[A](x: Seq[A]): Boolean = x match {
case h +: middle :+ t => h == t && isPalindrome(middle)
case _ => true
}
I would normally assume so however the extractor is actually
O(n). The extractor for anySeqisscala.collection.:+which hasO(n)for the list up to the last andO(n)for the last. The code for those two are the following:I see that the code does have this optimization. It makes sense because
t && isPalindrome(middle)allows Scala to close the current call stack, passtover to the next stack to be&&ed with, and hence it being tail-recursion optimisation-able.Constant time matching
Using
Vectorwe can achieveO(1)time: