Expand Around Center
Intuition
Every palindrome has a center point. For odd-length palindromes the center is a single character, and for even-length palindromes the center is between two adjacent characters. We iterate through all possible centers and expand outward as long as the characters on both sides match. Each successful expansion corresponds to one palindromic substring. Since there are 2n - 1 possible centers and each expansion takes at most O(n) time, this is an efficient O(n^2) solution with constant space.
Algorithm
- Initialize a counter to zero.
- For each index `i` in the string, expand around center for odd-length palindromes (`left = i, right = i`).
- For each index `i`, also expand around center for even-length palindromes (`left = i, right = i + 1`).
- During each expansion, while `left >= 0`, `right < n`, and `s[left] == s[right]`, increment the counter and continue expanding.
- Return the total count.
O(n^2)SpaceO(1)Code (C++ · Java · Python · Go)
class Solution {
public:
int countSubstrings(string s) {
int n = s.size();
int count = 0;
auto expand = [&](int left, int right) {
while (left >= 0 && right < n && s[left] == s[right]) {
count++;
left--;
right++;
}
};
for (int i = 0; i < n; i++) {
expand(i, i);
expand(i, i + 1);
}
return count;
}
};class Solution {
public int countSubstrings(String s) {
int n = s.length();
int count = 0;
for (int i = 0; i < n; i++) {
count += expand(s, i, i);
count += expand(s, i, i + 1);
}
return count;
}
private int expand(String s, int left, int right) {
int count = 0;
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
count++;
left--;
right++;
}
return count;
}
}class Solution:
def countSubstrings(self, s: str) -> int:
n = len(s)
count = 0
def expand(left: int, right: int) -> int:
total = 0
while left >= 0 and right < n and s[left] == s[right]:
total += 1
left -= 1
right += 1
return total
for i in range(n):
count += expand(i, i)
count += expand(i, i + 1)
return countfunc countSubstrings(s string) int {
n := len(s)
count := 0
expand := func(left, right int) int {
total := 0
for left >= 0 && right < n && s[left] == s[right] {
total++
left--
right++
}
return total
}
for i := 0; i < n; i++ {
count += expand(i, i)
count += expand(i, i+1)
}
return count
}