Loading problems...
TL;DR: The optimal solution iterates through every possible center of a palindrome (both single characters and pairs of characters) and expands outward using two pointers to count valid palindromes.
The LeetCode 647 problem, titled Palindromic Substrings, asks us to count the total number of contiguous substrings within a given string s that are palindromes. A palindrome is defined as a sequence that reads the same forwards and backwards.
For example, in the string "aaa", the palindromic substrings are "a", "a", "a" (indices 0, 1, 2), "aa", "aa" (indices 0-1, 1-2), and "aaa" (indices 0-2), resulting in a total of 6.
The naive approach involves generating every possible substring and verifying if each one is a palindrome.
i) and end (j) of every substring.s[i...j], iterate from the ends inward to check if it reads the same forwards and backwards.Pseudo-code:
textcount = 0 for i from 0 to length - 1: for j from i to length - 1: if isPalindrome(s, i, j): count++ return count
Complexity Analysis:
The intuition behind the optimal LeetCode 647 solution lies in the structure of a palindrome. Every palindrome mirrors around a central point.
If we know that a substring s[i...j] is a palindrome, we can determine if s[i-1...j+1] is a palindrome simply by checking if s[i-1] == s[j+1]. This suggests we should process the string from the inside out.
However, a palindrome can have two types of centers:
For a string of length , there are single-character centers and two-character centers, totaling centers. By placing two pointers at a center and moving them in opposite directions, we can count all palindromes originating from that center in linear time relative to the palindrome's length.
Visual Description: Imagine the string laid out horizontally. For every index , we initiate two expansion processes.

Let's trace the algorithm with s = "abc".
count = 0, n = 3.left=0, right=0. s[0] == s[0]. Valid. count becomes 1. Expand: left=-1, right=1. Out of bounds. Stop.left=0, right=1. s[0] != s[1] ('a' != 'b'). Stop.left=1, right=1. s[1] == s[1]. Valid. count becomes 2. Expand: left=0, right=2. s[0] != s[2] ('a' != 'c'). Stop.left=1, right=2. s[1] != s[2] ('b' != 'c'). Stop.left=2, right=2. s[2] == s[2]. Valid. count becomes 3. Expand: left=1, right=3. Out of bounds. Stop.left=2, right=3. Out of bounds. Stop.The algorithm is correct because every palindromic substring has a unique center. By iterating through all possible centers (indices for odd length, gaps between indices for even length) and expanding maximally, we are guaranteed to visit every palindromic substring exactly once. The expansion logic strictly adheres to the definition of a palindrome: if the characters at the current boundaries match, the substring is a palindrome; if they do not, no further expansion can yield a palindrome.
cppclass Solution { public: int countSubstrings(string s) { int count = 0; int n = s.length(); for (int i = 0; i < n; i++) { // Odd length palindromes (single character center) expandAroundCenter(s, i, i, count); // Even length palindromes (two character center) expandAroundCenter(s, i, i + 1, count); } return count; } private: void expandAroundCenter(const string& s, int left, int right, int& count) { while (left >= 0 && right < s.length() && s[left] == s[right]) { count++; left--; right++; } } };
javaclass Solution { public int countSubstrings(String s) { int count = 0; for (int i = 0; i < s.length(); i++) { // Odd length palindromes count += expandAroundCenter(s, i, i); // Even length palindromes count += expandAroundCenter(s, i, i + 1); } return count; } private int expandAroundCenter(String s, int left, int right) { int found = 0; while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { found++; left--; right++; } return found; } }
pythonclass Solution: def countSubstrings(self, s: str) -> int: count = 0 n = len(s) def expand_around_center(left: int, right: int) -> int: local_count = 0 while left >= 0 and right < n and s[left] == s[right]: local_count += 1 left -= 1 right += 1 return local_count for i in range(n): # Odd length palindromes count += expand_around_center(i, i) # Even length palindromes count += expand_around_center(i, i + 1) return count
left, right, count) to track state. We do not use any auxiliary data structures proportional to the input size.The Two Pointers - Expanding From Center pattern is a powerful tool for string manipulation problems involving symmetry.
Why does my solution fail on inputs like "abba"?
i, i).Why is my solution getting Time Limit Exceeded (TLE)?
Why am I getting IndexOutOfBounds exceptions?
left >= 0 and right < s.length() before accessing characters in the while loop condition.Can I use a Set to store the palindromes?