如果 s[r] 在回文子串中,那么采用中心扩展法,当 s[l..r] 是回文子串,且 r-l+1\ge k 时,有状态转移方程
f[r+1] = \max(f[r+1], f[l]+1)
这两种情况取最大值。
最后答案为 f[n],这里 n 为 s 的长度。
代码实现时,由于长度为 x 的回文子串一定包含长为 x-2 的回文子串,所以回文子串的长度达到 k 就可以退出循环了。
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defmaxPalindromes(self, s: str, k: int) -> int: n = len(s) f = [0] * (n + 1) for i inrange(2 * n - 1): l, r = i // 2, i // 2 + i % 2# 中心扩展法 f[l + 1] = max(f[l + 1], f[l]) while l >= 0and r < n and s[l] == s[r]: if r - l + 1 >= k: f[r + 1] = max(f[r + 1], f[l] + 1) break l -= 1 r += 1 return f[n]
[sol1-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution { publicintmaxPalindromes(String S, int k) { vars= S.toCharArray(); varn= s.length; varf=newint[n + 1]; for (vari=0; i < 2 * n - 1; ++i) { intl= i / 2, r = l + i % 2; // 中心扩展法 f[l + 1] = Math.max(f[l + 1], f[l]); for (; l >= 0 && r < n && s[l] == s[r]; --l, ++r) if (r - l + 1 >= k) { f[r + 1] = Math.max(f[r + 1], f[l] + 1); break; } } return f[n]; } }
[sol1-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution { public: intmaxPalindromes(string s, int k){ int n = s.length(), f[n + 1]; memset(f, 0, sizeof(f)); for (int i = 0; i < 2 * n - 1; ++i) { int l = i / 2, r = l + i % 2; // 中心扩展法 f[l + 1] = max(f[l + 1], f[l]); for (; l >= 0 && r < n && s[l] == s[r]; --l, ++r) if (r - l + 1 >= k) { f[r + 1] = max(f[r + 1], f[l] + 1); break; } } return f[n]; } };
[sol1-Go]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
funcmaxPalindromes(s string, k int)int { n := len(s) f := make([]int, n+1) for i := 0; i < 2*n-1; i++ { l, r := i/2, i/2+i%2// 中心扩展法 f[l+1] = max(f[l+1], f[l]) for l >= 0 && r < n && s[l] == s[r] { if r-l+1 >= k { f[r+1] = max(f[r+1], f[l]+1) break } l-- r++ } } return f[n] }
funcmax(a, b int)int { if b > a { return b }; return a }