◀ THE GRIND — 1-D DYNAMIC PROGRAMMING

Longest Palindromic Substring

MEDIUM✓ CHIP-TIMEDLC #5 — FULL STATEMENT ↗

The drill: Somewhere inside a string sits its longest run that reads the same forwards and backwards. Find that substring.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

A string arrives, and somewhere inside it sits a contiguous run of characters that reads identically forwards and backwards — a palindrome.

Several different substrings might tie for the longest palindrome; any one of the longest is an acceptable answer, not a specific one among the ties.

The task is to return that substring itself — the actual run of characters, not its length or its position in the string.

EX 01
s = "a"
"a"
MINIMUM SIZE, SINGLE CHARACTER
EX 02
s = "xx"
"xx"
WHOLE STRING IS THE PALINDROME
EX 03
s = "level"
"level"
WHOLE STRING, ODD LENGTH
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

Testing every substring for the palindrome property costs a scan per candidate on top of the count of candidates — where is the redundant work hiding?

HINT 2 THE STRUCTURE

A palindrome is built outward from its center — a single character, or a gap between two — and stops growing the instant its two ends disagree. Every palindrome has exactly one center.

HINT 3 ONE STEP FROM THE ANSWER

Walk every possible center (n single-character centers, n-1 between-character centers), expand outward while the ends match, and keep the widest span you've seen.

COACH'S BOARD — THE PATTERN, STEP BY STEP
THE CENTER EXPANSIONPATTERN · EXPAND AROUND CENTERs = "banana"
b
a
n
a
n
a
BEST WINDOW SO FAR
— empty —
STEP 1

Every palindrome grows from a center — a single character or a gap. Walk each one, expanding while the ends still match.

STEP 1 / 7 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/longest-palindromic-substring.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)

        def expand(l: int, r: int) -> tuple:
            while l >= 0 and r < n and s[l] == s[r]:
                l -= 1
                r += 1
            return l + 1, r - 1                  # last valid window

        start, end = 0, 0
        for i in range(n):
            l1, r1 = expand(i, i)                 # odd-length center
            if r1 - l1 > end - start:
                start, end = l1, r1
            l2, r2 = expand(i, i + 1)              # even-length center
            if r2 - l2 > end - start:
                start, end = l2, r2
        return s[start:end + 1]
TIME O(N^2)SPACE O(1)PYTHON · RACE PACE · 19 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED