[LeetCode] 5. Longest Palindromi
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example:
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.```
######Example:
Input: "cbbd"
Output: "bb"```
</br>
Solution
The most straightforward way to implement this is to iterate all various substrings and individually check whether it is palindromic and outputs the longest one.
public class Solution {
public String longestPalindrome(String s) {
int i = 0, j = 0, k = 0, t = 0, max = 1;
int n = s.length();
boolean isPalindrome = false;
String maxString = new String();
Set<Character> set = new HashSet<>();
for (i = 0;i < n;i++){
for (j = i;j < n;j++){
for (k = 0;k <= j-i;){
if (s.charAt(i+k) == s.charAt(j-k))
isPalindrome = true;
else{
isPalindrome = false;
break;
}
k++;
}
if (isPalindrome){
if (max <= j-i+1){
max = j-i+1;
maxString = s.substring(i,j+1);
}
}
}
}
return maxString;
}
}
Clearly, this method may lead to Time Limit Exceeded.
Therefore a more efficient way is needed. Instead of inspecting every substring to check whether it is palindromic or not, we should try to build palindromic words from ground up. As abcdcba
, the words are mirrored from the middle character. Then if s[i,j]
is palindromic, we only have to check if the character in front of it and behind it is the same to determine whether s[i-1,j+1] is palindromic.
Hence, rather than iterating all substrings, we only have to check all the available middle spot. In a string of n
characters, there is a total of 2n-1
middle spots.
The code is shown below.
public class Solution {
public String longestPalindrome(String s) {
int l = 0, r = 0, max = 0;
for (int i = 0; i < s.length() ;i++){
int len1 = substringBuilder(s,i,i);
int len2 = substringBuilder(s,i,i+1);
int len = Math.max(len1,len2);
if(len > max){
l = i - (len-1)/2;
r = i + len/2 + 1;
max = len;
}
}
return s.substring(l, r);
}
public int substringBuilder(String s, int left, int right){
int start = left, end = right;
while (start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)){
start --;
end ++;
}
return end - start - 1;
}
}
The trick in the solution is to focus on the output on the substringBuilder, because we compare two situation of middle points at s[i,i]
and s[i,i+1]
, if the middle point is at the s[i,i+1]
, then the length of the palindromic substring is even, which means the least length is 0 or 2; then we should return end - start - 1
as the length of the substring instead of end - start
.
</br>