palindrome substrings
string algorithms
palindrome detection
coding interview
computational problem-solving

Find all substrings that are palindromes

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The usual goal in this problem is to find every palindromic substring occurrence in a string, not just the unique palindrome values. For example, in "aaa", the substring "a" appears three times, and each occurrence counts if you are enumerating all palindromic substrings by position.

There are several ways to solve the problem, but for most interview and production situations, expanding around centers is the best balance of simplicity and performance.

Why center expansion works

Every palindrome has a center. Odd-length palindromes have one middle character, and even-length palindromes have a center between two characters.

That means you can iterate over all possible centers and expand outward while the characters match.

For the string "abba":

  • center at "b" finds odd palindromes such as "b"
  • center between the two "b" characters finds "bb" and then "abba"

This avoids generating every possible substring and checking each one from scratch.

A practical O(n^2) solution

Here is a Python implementation that returns every palindromic substring occurrence:

python
1def all_palindromic_substrings(s: str) -> list[str]:
2    result: list[str] = []
3
4    def expand(left: int, right: int) -> None:
5        while left >= 0 and right < len(s) and s[left] == s[right]:
6            result.append(s[left:right + 1])
7            left -= 1
8            right += 1
9
10    for center in range(len(s)):
11        expand(center, center)       # odd length
12        expand(center, center + 1)   # even length
13
14    return result
15
16
17print(all_palindromic_substrings("abba"))

Output:

python
['a', 'b', 'bb', 'abba', 'b', 'a']

The time complexity is O(n^2) in the worst case, which happens on strings such as "aaaaa" where many centers expand a long way. The extra space is O(1) beyond the output list itself.

Return positions if you need more control

Sometimes returning raw substrings is not ideal because duplicate values lose positional information. In that case, return index pairs instead:

python
1def palindromic_ranges(s: str) -> list[tuple[int, int]]:
2    result: list[tuple[int, int]] = []
3
4    def expand(left: int, right: int) -> None:
5        while left >= 0 and right < len(s) and s[left] == s[right]:
6            result.append((left, right))
7            left -= 1
8            right += 1
9
10    for center in range(len(s)):
11        expand(center, center)
12        expand(center, center + 1)
13
14    return result
15
16
17print(palindromic_ranges("aaa"))

This is useful if you later want to highlight matches in a UI or count them without allocating many duplicate substring objects.

How this compares with brute force and dynamic programming

The brute-force method checks every substring and tests whether it is a palindrome. That leads to O(n^3) time in the usual implementation, which is too slow for long inputs.

Dynamic programming also reaches O(n^2) time, but it uses additional O(n^2) space for a table of palindrome states. That can be useful when you need related information such as longest-palindrome reconstruction, but it is more memory-heavy than center expansion.

So for the plain "find all palindromic substrings" task:

  • brute force is easiest to discover but slow
  • dynamic programming is valid but heavier
  • center expansion is usually the best practical answer

Be clear about duplicates and normalization

Interview questions sometimes leave out an important detail: do you want all palindromic occurrences or only distinct palindrome strings?

If you want unique values only, you can collect them in a set:

python
def unique_palindromes(s: str) -> set[str]:
    return set(all_palindromic_substrings(s))

That changes the output format, but not the underlying search complexity. It also removes positional duplicates, which may or may not be what the problem expects.

Common Pitfalls

The most common mistake is forgetting even-length palindromes. If you only expand around a single character, you miss values such as "aa" and "abba".

Another issue is misunderstanding duplicates. "aaa" contains multiple palindromic occurrences that share the same text value, and many solutions accidentally collapse them when the requirement was to list all occurrences.

Developers also sometimes slice substrings too early in performance-sensitive code. Returning ranges first can reduce extra allocation if the caller does not need the actual substring text immediately.

Finally, do not reach for the brute-force approach unless the string is tiny or the problem is purely educational. Center expansion gives a much better performance-to-complexity tradeoff.

Summary

  • Expanding around centers is the standard practical way to find all palindromic substrings.
  • You must check both odd-length and even-length centers.
  • The center-expansion approach runs in O(n^2) time in the worst case.
  • Return index ranges instead of substring copies when positional information matters.
  • Clarify whether the problem wants all occurrences or only unique palindrome values.

Course illustration
Course illustration

All Rights Reserved.