Longest Palindromic Substring (Leetcode #5)
Finding the longest palindromic substring in a given string is one of the most frequently asked questions in coding interviews, especially for roles that involve algorithms and data structures. This problem not only tests your understanding of dynamic programming but also helps you master how to optimize complex solutions. In this blog, we will explore a brute force method, delve into an efficient approach using dynamic programming, and break down the time and space complexities involved. Let's dive in!
Understanding the Problem Statement
The goal of the "Longest Palindromic Substring" problem is to find the longest substring within a given string that reads the same backward as forward. The input is a string of characters, and you need to return the longest palindromic substring. For example, if the input string is "babad", the answer could be "bab" or "aba".
Brute Force Approach
The most intuitive way to solve this problem is the brute force method, where we generate all possible substrings and check whether each one is a palindrome. This can be done by iterating over all possible starting and ending points of the substring and then reversing each substring to verify if it matches the original.
In Python, the brute force approach might look something like this:
Iterate over all pairs of start and end indices.
Check if the substring is a palindrome by reversing it.
Keep track of the longest palindrome found.
The brute force solution will have a time complexity of O(n^3) since it takes O(n^2) to generate all substrings and O(n) to check if each substring is a palindrome.
Hint to Solve the Problem Efficiently
A more efficient approach involves using dynamic programming to keep track of palindromes in a 2D table. The key idea here is that a substring is a palindrome if its boundary characters are equal and the substring within those boundaries is also a palindrome. By storing these intermediate results, we can avoid redundant calculations.
Efficient Solution
Here is the provided efficient solution that leverages dynamic programming to reduce the time complexity:
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n < 2:
return s
dp = [[False] * n for _ in range(n)]
# Initialize start position and max length of the palindrome
start, max_length = 0, 1
# Base case: single character palindromes
for i in range(n):
dp[i][i] = True
# Base case: two-character palindromes
for i in range(n-1):
if s[i] == s[i+1]:
dp[i][i+1] = True
if dp[i][i+1]:
start, max_length = i, 2
# General case
for length in range(3, n+1):
for i in range(n-length+1):
j = i + length - 1
if s[i] == s[j] and dp[i+1][j-1]:
dp[i][j] = True
start, max_length = i, length
return s[start:start+max_length]
Explanation of the Code
Initialization: We first initialize a 2D list
dp
to store whether a substring is a palindrome.dp[i][j]
is True if the substring fromi
toj
is a palindrome.Base Cases: We initialize all single-character substrings as palindromes (
dp[i][i] = True
). We also handle the two-character substrings.General Case: We iterate through possible substring lengths, starting from 3. For each substring of a given length, we check if its boundary characters are the same and if the substring within those boundaries is also a palindrome.
Return Value: We track the starting position and length of the longest palindromic substring found, which allows us to return the desired result.
Time and Space Complexity
Time Complexity: The efficient solution has a time complexity of O(n^2). This is because we fill out a 2D table of size
n x n
by iterating over all substrings of increasing length.Space Complexity: The space complexity is also O(n^2), as we store the results for all possible substrings in a 2D list. This helps in avoiding redundant calculations and contributes to the optimized solution.
Conclusion
The "Longest Palindromic Substring" problem can initially seem challenging, especially with the brute force approach being highly inefficient. However, with the help of dynamic programming, we can significantly reduce the time complexity and solve the problem effectively. Mastering this efficient approach will not only help you tackle similar problems but also improve your overall problem-solving skills for coding interviews.