{x}
blog image

Longest Palindromic Substring

Given a string s, return the longest palindromic substring in s.

 

Example 1:

Input: s = "babad"
Output: "bab"
Explanation: "aba" is also a valid answer.

Example 2:

Input: s = "cbbd"
Output: "bb"

 

Constraints:

  • 1 <= s.length <= 1000
  • s consist of only digits and English letters.

Solution Explanation: Longest Palindromic Substring

The problem asks to find the longest palindromic substring within a given string. Two efficient solutions are presented: Dynamic Programming and the Expand Around Center approach.

Solution 1: Dynamic Programming

This approach uses a 2D boolean array dp where dp[i][j] is true if the substring s[i...j] is a palindrome, and false otherwise.

Algorithm:

  1. Initialization: The diagonal of the dp array (where i == j) is initialized to true because single characters are palindromes.

  2. Iteration: The algorithm iterates through the dp array, filling it in a bottom-up manner. For each pair (i, j), it checks:

    • If s[i] == s[j], then dp[i][j] is true if dp[i+1][j-1] is also true (meaning the inner substring is a palindrome).
    • Otherwise, dp[i][j] is false.
  3. Tracking the Longest Palindrome: While filling dp, the algorithm keeps track of the starting index (start) and length (maxLength) of the longest palindrome found so far.

Code (Python):

class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        dp = [[False] * n for _ in range(n)]
        start = 0
        maxLength = 1
 
        for i in range(n):
            dp[i][i] = True  # Single characters are palindromes
 
        for length in range(2, n + 1):  # Iterate through substring lengths
            for i in range(n - length + 1):
                j = i + length - 1
                if s[i] == s[j]:
                    if length == 2 or dp[i + 1][j - 1]:
                        dp[i][j] = True
                        if length > maxLength:
                            maxLength = length
                            start = i
 
        return s[start:start + maxLength]
 

Time Complexity: O(n^2) - due to nested loops iterating through all possible substrings. Space Complexity: O(n^2) - to store the dp array.

Solution 2: Expand Around Center

This approach is more concise and space-efficient. It iterates through each character (or pair of adjacent characters) in the string, treating them as potential centers of a palindrome. It then expands outwards from the center to find the longest palindrome with that center.

Algorithm:

  1. Iteration: Iterate through each index i of the string.

  2. Expand Odd Length Palindromes: Treat i as the center of an odd-length palindrome. Expand outwards (i-1, i+1, i-2, i+2, etc.) until the characters don't match or the boundaries are reached. Record the length and start index if it's the longest palindrome found so far.

  3. Expand Even Length Palindromes: Treat i and i+1 as the centers of an even-length palindrome. Expand outwards similarly, recording the length and start index if it's the longest.

Code (Python):

class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        start = 0
        maxLength = 1
 
        for i in range(n):
            # Odd length palindromes
            l, r = i, i
            while l >= 0 and r < n and s[l] == s[r]:
                if r - l + 1 > maxLength:
                    maxLength = r - l + 1
                    start = l
                l -= 1
                r += 1
 
            # Even length palindromes
            l, r = i, i + 1
            while l >= 0 and r < n and s[l] == s[r]:
                if r - l + 1 > maxLength:
                    maxLength = r - l + 1
                    start = l
                l -= 1
                r += 1
 
        return s[start:start + maxLength]

Time Complexity: O(n^2) - although it avoids a nested loop structure, the while loops can expand outwards to at most O(n) in the worst case, giving an overall quadratic time complexity. Space Complexity: O(1) - constant extra space is used.

Conclusion:

Both approaches solve the problem correctly. The Expand Around Center method is generally preferred due to its slightly improved space complexity. The choice of which to use might depend on personal preference and coding style. The dynamic programming solution may be easier to understand for some. Both have the same time complexity.