HARD Lab · Strings · 20

647. Palindromic Substrings

Count every palindromic substring by treating each of the 2n − 1 possible centers as a seed and expanding outward with two pointers — each successful expansion is exactly one new palindrome.

MediumExpand Around CenterTypeScript

PROBLEM What we're solving

Given a string s, return the number of substrings that are palindromes. Every single character counts. For s = "aaa" the palindromic substrings are "a" (×3), "aa" (×2), and "aaa" (×1) — six total, so the answer is 6. For s = "abc" only the three single characters qualify, giving 3.

KEY IDEA Every palindrome has exactly one center

Insight → every palindrome grows symmetrically around a center. A length-n string has exactly n odd-length centers (single characters) and n − 1 even-length centers (gaps between characters) — 2n − 1 centers total. Seed each one, expand both pointers outward while s[l] === s[r], and increment count on every match: that expansion is a distinct palindrome.

RECIPE Iterate centers, expand, count

  • 0 · Index all centers. Loop c from 0 to 2n − 2. Odd centers (c even) start at l = r = c / 2. Even centers (c odd) start at l = ⌊c/2⌋, r = l + 1. One loop, no branches needed.
  • 1 · Expand. while (l >= 0 && r < n && s[l] === s[r]): increment count, then move l--; r++. Each iteration is a confirmed new palindrome.
  • 2 · Stop. The moment s[l] !== s[r] (or a pointer goes out of bounds), break — no wider palindrome can exist at this center.
  • 3 · Return. After all centers, count holds the total.
Classic confusion → students often code separate loops for odd and even centers and forget one of the two. The single c = 0..2n-2 trick unifies them: when c is even r starts equal to l (odd-length), when c is odd r = l + 1 (even-length). One loop, no missed cases.

COST Complexity & alternatives

Check every substring
O(n³)
O(n²) pairs × O(n) verify each.
Expand around center
O(n²)
O(n) centers × O(n) expansion. O(1) space.

Manacher's algorithm

The O(n) Manacher's algorithm reuses previously computed palindrome radii to skip redundant expansions. It's rarely asked in interviews — expand-around-center at O(n²) is the expected answer. Mention Manacher's as a follow-up to show depth.

Pattern transfer → the same expand-around-center logic drives Longest Palindromic Substring (LC 5, track the max radius instead of a count), Palindrome Partitioning (precompute the palindrome table with this technique), and Longest Palindromic Subsequence (which instead uses 2D DP but shares the symmetric intuition).

RUN IT Expand around every center, count each palindrome

step 0 / 18
STARTString "aaa", length 3. Iterating 5 centers (3 odd + 2 even). Count = 0.
a0a1a2
State
center
l
r
0
count
l / r pointersconfirmed palindrome span
slowfast

TYPESCRIPT The solution, annotated

countSubstrings.ts
function countSubstrings(s: string): number {
  let count = 0;
  const n = s.length;

  // Try every possible center (n odd + n-1 even = 2n-1 centers)
  for (let c = 0; c < 2 * n - 1; c++) {
    let l = Math.floor(c / 2);
    let r = l + (c % 2 === 0 ? 0 : 1);   // odd center: r = l; even: r = l+1

    // Expand outward while characters match
    while (l >= 0 && r < n && s[l] === s[r]) {
      count++;
      l--;
      r++;
    }
  }

  return count;
}

Reading it block by block

Line 5 — initialize. count accumulates every palindrome found. nis cached so we don't recompute the length.
Lines 8–9 — center indexing. The single loop over c = 0..2n-2 encodes both odd and even centers. When c % 2 === 0, both pointers start at the same character (odd-length palindrome seed). When c % 2 === 1, r = l + 1 seeds an even-length palindrome across the gap. No separate loops needed.
Lines 12–15 — expand and count. Each iteration where s[l] === s[r] confirms a distinct palindromic substring — count it, then widen. The while condition l >= 0 && r < n guards bounds before the character comparison.
Line 18 — return total. After exhausting all centers, count holds the exact number of palindromic substrings.
Complexity → O(n²) time: 2n − 1 centers, each expands at most O(n/2) steps. O(1) extra space — only two integer pointers and a counter.

INTERVIEWFollow-ups they'll ask

  • "Return the longest palindromic substring instead of the count?" Track the start index and max radius during expansion; reconstruct with s.slice(start - radius, start + radius + 1).
  • "Can you do it in O(n)?" Manacher's algorithm reuses a "mirror" radius array to skip redundant expansions — worth mentioning, rarely expected to code.
  • "What about Palindrome Partitioning?" Run expand-around-center first to precompute a boolean isPalin[i][j] table, then backtrack using it as an O(1) check.
  • "What if the string contains only one distinct character?" Every substring is a palindrome, so the answer is n*(n+1)/2 — a good sanity check for your solution.
  • "Brute force?" Check all O(n²) pairs and verify each palindrome in O(n) → O(n³) total. Expand-around-center is O(n²) and avoids redundant character comparisons.

MNEMONIC The one-liner

"Plant a flag at every gap and character; expand both wings until they disagree."

TRIGGERS When you see ___ → reach for ___

"count palindromic substrings"expand around center (2n−1 seeds)
"longest palindromic substring"expand around center, track max radius
symmetric structure around a midpointtwo-pointer expansion from center
"palindrome partition / precompute isPalin"run expand-center to fill table

SKELETON The reusable shape

skeleton.ts
function countSubstrings(s: string): number {
  let count = 0;
  const n = s.length;
  for (let c = 0; c < 2 * n - 1; c++) {
    let l = Math.floor(c / 2);
    let r = l + (c % 2 === 0 ? 0 : 1);
    while (l >= 0 && r < n && s[l] === s[r]) {
      count++;
      l--;
      r++;
    }
  }
  return count;
}

FLASHCARDS Tap to flip

How many centers does a length-n string have?
2n − 1: n odd-length centers (single chars) + (n−1) even-length centers (gaps between chars).
tap to flip
1 / 7
Answer to reveal explanations. No penalty for retries.Score: 0 / 7
QUESTION 01
For s = "aaa", how many palindromic substrings are there?
QUESTION 02
What is the time complexity of the expand-around-center approach?
QUESTION 03
How many centers does a string of length n have?
QUESTION 04
In the single-loop encoding, when c is odd, what are the starting values ofl and r?
QUESTION 05
What is the space complexity of the expand-around-center solution?
QUESTION 06
Why does incrementing count inside the while loop (before moving the pointers) give the correct total?
QUESTION 07
A string of all identical characters (e.g. "aaaa", length n) has how many palindromic substrings?