'Why did my code get TLE on leetcode since I actually evaluate each slot only once?

I'm trying to solve problem longest palindromic substring in leetcode in a functional way (using LazyList as cache). However, I got TLE result and I don't know why. Can anyone explain why this code is not efficient?

object Solution {
    def longestPalindrome(s: String): String = {
        val n = s.length
        var ans = (0, 0)
        var cnt = 1
        def logic(i: Int, j: Int): Int = (i, j) match {
            case (i, j) if i >  j       => -1
            case (i, j) if i == j       => 1
            case (i, j) if s(i) != s(j) => 0
            case (i, j) if i + 1 == j   => 2
            case (i, j) => 
                if(mem(i + 1)(j - 1) == 0) 0
                else j - i + 1
        }
        lazy val mem: LazyList[LazyList[Int]] = LazyList.tabulate(n, n) {
            case (i, j) => {
                val n = logic(i, j)
                if(n > cnt) {
                    cnt = n
                    ans = (i, j)
                }
                n
            }
        }
        mem.foreach(_.force)
        // println(mem)
        ans match {
            case (i, j) => s.slice(i, j + 1)
        }
    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source