-
Difficulty: Medium
-
Related Topics: String, Dynamic Programming
Description
Given a string, your task is to count how many palindromic substrings in this string.
给一个字符串,你的任务是统计其中有多少回文子串。
The substrings with different start indices or end indices are counted as different substrings even they consist of same characters.
起始索引和终止索引有一个不同即视为不同的回文子串,哪怕它们由相同的字符构成。
Examples
Example 1
Input: "abc"
Output: 3
Explanation: Three palindromic strings: "a", "b", "c".
Example 2
Input: "aaa"
Output: 6
Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".
Note
- The input string length won't exceed 1000.
输入字符串的长度不会超过 1000。
Hints
-
How can we reuse a previously computed palindrome to compute a larger palindrome?
如何使用之前的回文子串结果生成新的回文子串? -
If "aba" is a palidrome, is "xabax" a palindrome? Similarly is "xabay" a palidrome?
如果 "aba" 是回文,那么 "xabax" 回文吗?类似地,"xabay" 回文吗? -
Complexity based hint:
If we use brute-force and check whether for every start and end position a substring is a palindrome we have O(n^2) start-end pairs and O(n) palindromic check. Can we reduce the time for palindromic checks to O(1) by reusing some previous computation?
如果我们暴力枚举并检查每一个子串是否回文,我们需要检查 (O(N^2)) 的 start-end 对和 (O(N)) 的回文检查。我们是否能通过利用之前的计算,将回文检查的时间减少到 (O(1))?
Solution
暴力解法:从字符串的每个元素开始,从中间向外扩张寻找回文,实际跑下来时间竟然还行,代码如下:
class Solution {
private var count = 0
fun countSubstrings(s: String): Int {
for (i in s.indices) {
expand(s, i, i)
expand(s, i, i + 1)
}
return count
}
private fun expand(s: String, left: Int, right: Int) {
var mLeft = left
var mRight = right
while (mLeft >= 0 && mRight <= s.lastIndex && s[mLeft] == s[mRight]) {
count++
mLeft--
mRight++
}
}
}