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.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.
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:
Initialization: The diagonal of the dp
array (where i == j
) is initialized to true
because single characters are palindromes.
Iteration: The algorithm iterates through the dp
array, filling it in a bottom-up manner. For each pair (i, j)
, it checks:
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).dp[i][j]
is false
.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.
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:
Iteration: Iterate through each index i
of the string.
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.
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.