Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Find all distinct palindromic sub-strings of a given String in Python
Finding all distinct palindromic substrings is a common string processing problem. A palindrome is a string that reads the same forwards and backwards. This solution uses Manacher's algorithm to efficiently find all palindromic substrings.
So, if the input is like "bddaaa", then the output will be [a, aa, aaa, b, d, dd]
Understanding the Algorithm
The algorithm follows these key steps:
- Create a matrix to store palindrome lengths at each position
- Process the string with padding characters to handle edge cases
- Use Manacher's algorithm to find all palindromes efficiently
- Extract distinct palindromic substrings using a dictionary
Example
Let us see the following implementation to get better understanding ā
def find_substr(s):
m = dict()
n = len(s)
matrix = [[0 for x in range(n+1)] for x in range(2)]
s = "@" + s + "#"
for j in range(2):
temp = 0
matrix[j][0] = 0
i = 1
while i <= n:
while s[i - temp - 1] == s[i + j + temp]:
temp += 1
matrix[j][i] = temp
k = 1
while (matrix[j][i - k] != temp - k) and (k < temp):
matrix[j][i+k] = min(matrix[j][i-k], temp - k)
k += 1
temp = max(temp - k, 0)
i += k
s = s[1:len(s)-1]
m[s[0]] = 1
for i in range(1,n):
for j in range(2):
for temp in range(matrix[j][i],0,-1):
m[s[i - temp - 1 : i - temp - 1 + 2 * temp + j]] = 1
m[s[i]] = 1
return sorted(m.keys())
# Test the function
result = find_substr("bddaaa")
for palindrome in result:
print(palindrome)
The output of the above code is ā
a aa aaa b d dd
How It Works
The algorithm works in two phases:
- Phase 1: Build a matrix using Manacher's algorithm to store palindrome radii
- Phase 2: Extract all palindromic substrings using the computed matrix
The padding characters "@" and "#" help handle boundary conditions during palindrome detection.
Alternative Simple Approach
Here's a simpler approach for better understanding ā
def find_palindromes_simple(s):
palindromes = set()
n = len(s)
# Check all possible substrings
for i in range(n):
for j in range(i+1, n+1):
substring = s[i:j]
if substring == substring[::-1]:
palindromes.add(substring)
return sorted(palindromes)
# Test the simple approach
result = find_palindromes_simple("bddaaa")
for palindrome in result:
print(palindrome)
a aa aaa b d dd
Comparison
| Method | Time Complexity | Space Complexity | Best For |
|---|---|---|---|
| Manacher's Algorithm | O(n) | O(n) | Large strings |
| Simple Approach | O(n³) | O(1) | Small strings, learning |
Conclusion
Manacher's algorithm efficiently finds all palindromic substrings in linear time. For simpler cases, the brute force approach is easier to understand and implement.
