Python Program to Find All Palindrome Substrings
expand_around_center and collecting substrings where left == right while expanding.Examples
How to Think About It
Algorithm
Code
def find_palindromes(s): result = [] def expand_around_center(left, right): while left >= 0 and right < len(s) and s[left] == s[right]: result.append(s[left:right+1]) left -= 1 right += 1 for i in range(len(s)): expand_around_center(i, i) # odd length expand_around_center(i, i + 1) # even length return result input_str = "abba" print(find_palindromes(input_str))
Dry Run
Let's trace 'abba' through the code
Start with i=0 (center at 'a')
Expand around center (0,0): substring 'a' is palindrome, add 'a'. Expand stops as next chars differ.
Check even center (0,1) between 'a' and 'b'
Characters differ, no palindrome added.
i=1 (center at 'b')
Expand around (1,1): 'b' added. Expand around (1,2): 'bb' added, then expand further to 'abba' added.
i=2 (center at 'b')
Expand around (2,2): 'b' added. Expand around (2,3): 'ba' no palindrome.
i=3 (center at 'a')
Expand around (3,3): 'a' added. Expand around (3,4): out of bounds.
| Center | Palindromes Found |
|---|---|
| (0,0) | a |
| (0,1) | |
| (1,1) | b |
| (1,2) | bb, abba |
| (2,2) | b |
| (2,3) | |
| (3,3) | a |
| (3,4) |
Why This Works
Step 1: Expand Around Centers
The code checks palindromes by expanding around each character and between characters, because palindromes can be odd or even length.
Step 2: Check Characters Match
While expanding, it compares characters on both sides; if they match, the substring is a palindrome.
Step 3: Collect Palindromes
Each time a palindrome substring is found, it is added to the result list.
Alternative Approaches
def find_palindromes_dp(s): n = len(s) dp = [[False]*n for _ in range(n)] result = [] for length in range(1, n+1): for start in range(n-length+1): end = start + length - 1 if s[start] == s[end] and (length <= 2 or dp[start+1][end-1]): dp[start][end] = True result.append(s[start:end+1]) return result print(find_palindromes_dp('abba'))
def is_palindrome(sub): return sub == sub[::-1] def find_palindromes_brute(s): result = [] for i in range(len(s)): for j in range(i, len(s)): if is_palindrome(s[i:j+1]): result.append(s[i:j+1]) return result print(find_palindromes_brute('abba'))
Complexity: O(n^2) time, O(n^2) space
Time Complexity
The algorithm expands around each character and between characters, each expansion can take up to O(n), repeated for n centers, resulting in O(n^2).
Space Complexity
The result list can hold up to O(n^2) substrings in the worst case, so space is O(n^2).
Which Approach is Fastest?
The expand-around-center method is generally faster and simpler than brute force, and uses less memory than dynamic programming.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Expand Around Center | O(n^2) | O(n^2) | Balanced speed and memory |
| Dynamic Programming | O(n^2) | O(n^2) | Repeated palindrome queries |
| Brute Force | O(n^3) | O(n^2) | Simple but slow, small inputs |