Palindromic Substrings
Count palindromic substrings of s using expand-around-center in O(n²).
3 min read
dp string
Problem#
Return the count of palindromic substrings (different starts or ends counted separately).
Examples#
"abc"→3"aaa"→6
Constraints#
1 <= n <= 1000.
Approach#
For each center (single char and inter-char), expand outward while characters match. Count each successful expansion.
Solution#
class Solution {public: int countSubstrings(string s) { int count = 0; for (int center = 0; center < (int)s.size(); ++center) { count += expand(s, center, center); count += expand(s, center, center + 1); } return count; }private: int expand(const string& s, int l, int r) { int n = 0; while (l >= 0 && r < (int)s.size() && s[l] == s[r]) { ++n; --l; ++r; } return n; }};func countSubstrings(s string) int { expand := func(l, r int) int { n := 0 for l >= 0 && r < len(s) && s[l] == s[r] { n++ l-- r++ } return n } count := 0 for center := 0; center < len(s); center++ { count += expand(center, center) count += expand(center, center+1) } return count}class Solution: def countSubstrings(self, s: str) -> int: def expand(l: int, r: int) -> int: n = 0 while l >= 0 and r < len(s) and s[l] == s[r]: n += 1 l -= 1 r += 1 return n
count = 0 for center in range(len(s)): count += expand(center, center) count += expand(center, center + 1) return countfunction countSubstrings(s) { const expand = (l, r) => { let n = 0; while (l >= 0 && r < s.length && s[l] === s[r]) { n++; l--; r++; } return n; }; let count = 0; for (let center = 0; center < s.length; center++) { count += expand(center, center); count += expand(center, center + 1); } return count;}class Solution { private String s;
public int countSubstrings(String s) { this.s = s; int count = 0; for (int center = 0; center < s.length(); center++) { count += expand(center, center); count += expand(center, center + 1); } return count; }
private int expand(int l, int r) { int n = 0; while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { n++; l--; r++; } return n; }}function countSubstrings(s: string): number { const expand = (l: number, r: number): number => { let n = 0; while (l >= 0 && r < s.length && s[l] === s[r]) { n++; l--; r++; } return n; }; let count = 0; for (let center = 0; center < s.length; center++) { count += expand(center, center); count += expand(center, center + 1); } return count;}Editorial#
Expand-around-center is O(n²) worst-case but cleaner than O(n²) 2D DP. There are 2n - 1 possible centers (n single-char + n-1 between-char). Manacher’s gives O(n) but is much more complex.
Complexity#
- Time: O(n²).
- Space: O(1).
Concept revision#
Related#