Palindromes found one chip per match, in the order the centres find them
public int countSubstrings(String s) { int res = 0; for (int i = 0; i < s.length(); i++) { res += countPali(s, i, i); // odd res += countPali(s, i, i + 1); // even } return res;} private int countPali(String s, int l, int r) { int res = 0; while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { res++; l--; r++; } return res;}
- i
- —
- l, r
- —
- this centre
- —
- res
- 0
Why it works
- Brute force checks every substring: O(n²) of them, O(n) each to test, so O(n³).
- Each palindrome has exactly one centre, a character or the gap between two. Expanding from a centre finds its palindromes shortest first, and the first mismatch rules out every longer one. So each match is one new palindrome, never counted twice.
- 2n − 1 centres, at most n/2 expansions each: O(n²) time in the worst case (all one letter), O(1) space.
- Pitfall: skipping the even centres.
"abba"has 6 palindromes, and"bb"and"abba"only show up from the gap between the two b's. - Related: Longest Palindromic Substring runs the same loops but keeps the longest span instead of a count. The dp alternative fills
dp[l][r] = s.charAt(l) == s.charAt(r) && dp[l+1][r−1]in O(n²) space.