Medium草稿★★★★★O(n^2) 時間 · O(1) 空間
Dynamic ProgrammingStringTwo Pointers
Patterns📈 線性 DP・Kadane↔️ 雙指針
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

647Palindromic Substrings1-D DPMedium1-D DP

給定一個字串 s,計算其中有多少個回文子字串。具有不同起始或結束位置的子字串即使內容相同也視為不同的子字串。

Example:

Input: s = “aaa” Output: 6

Intuition

TIP

和最長回文子字串同一套路:從每個中心向外擴展,每擴展成功一次就多一個回文。

Approaches

1. Dynamic Programming — O(n^2) / O(n^2)
  • Idea: dp[i][j] 表示 s[i..j] 是否為回文,遍歷所有子字串並計數
  • Time: O(n^2)
  • Space: O(n^2)
class Solution {
    fun countSubstrings(s: String): Int {
        val n = s.length
        val dp = Array(n) { BooleanArray(n) }
        var count = 0
        for (len in 1..n) {
            for (i in 0..n - len) {
                val j = i + len - 1
                dp[i][j] = s[i] == s[j] && (len <= 2 || dp[i + 1][j - 1])
                if (dp[i][j]) count++
            }
        }
        return count
    }
}
⭐ 2. Expand Around Center — O(n^2) / O(1)
  • Idea: 對每個中心(奇偶兩種)擴展,每次擴展成功就累加計數
  • Time: O(n^2)
  • Space: O(1)
class Solution {
    fun countSubstrings(s: String): Int {
        var count = 0
        fun expand(l: Int, r: Int) {
            var left = l; var right = r
            while (left >= 0 && right < s.length && s[left] == s[right]) {
                count++
                left--; right++
            }
        }
        for (i in s.indices) {
            expand(i, i)     // 奇數長度
            expand(i, i + 1) // 偶數長度
        }
        return count
    }
}

🔑 Takeaways

Ladders 看全部 →