Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example 1:
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Example 2:
Input: "cbbd"
Output: "bb"
Solution
The obvious brute-force solution is to populate all possible substring and check if each of them is a palindromic string, which gives you quadratic time complexity. However, we realize that there are a lot of repetitive calculations when performing permutation. Thus, instead of thinking through from two sides, we can try to expand the string from the middle. For example, consider a string “aba”. From the middle, “b” itself is a palindromic substring, so we expand from the middle to left and right. We find that left and right boundary are both “a”, then the whole string is a palindromic string.
However, we also need to consider even-length strings. Consider the string “abba”, which is also a palindromic string. How can we use same expand technique? Well, we can simply use two index to expand from the middle, instead of one, like the example “aba”.
Let’s work through a provided example “babad”. From the first index, which is “b”, we know that it is a palindromic substring, so we expand from the middle. Since we are find the longest palindromic substring, we can perform two checks simultaneously to check even and odd condition. For odd, we expand from itself. For odd, we expand from i + 1. After checking its boundary, we know that the right most boundary for this string, we move our index to next appropriate position to populate using the same technique again. Here is an implementation.
class Solution {
public String longestPalindrome(String s) {
int maxLength = 0;
int start = 0;
for(int i = 0; i < s.length(); i++) {
int expanded_length = Math.max(genLength(s, i, i), genLength(s, i, i + 1));
if (expanded_length > maxLength) {
maxLength = expanded_length;
start = i - (expanded_length - 1) / 2;
}
}
return s.substring(start, start + maxLength);
}
private int genLength(String s, int left, int right) {
while(left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return right - left - 1;
}
}
Time Complexity
Running Time: O(n^2)
Space Time: O(1)