Longest Palindrome Substring
Given a string ss
Note: A string is palindromic if it reads the same forward and backward. For example abcba is a palindromic string that expands from center letter c and abba is also a palindromic string that expands with no center letter.
Example 1
Output: "bab" or "aba"
Explanation: there are two longest palindromic substring in the input "bab" and "aba" and both are of length 3, so you return any one of them.
Example 2
Output: "bb"
Explanation: longest palindromic substring is "bb".
Solution 1 - using brute force approach
In this approach, we will generate all possible substrings, then for each substring check if that is a valid palindrome.
-
We will create a function
that takesbruteForceApproach as input string.s -
Then, we will create all possible substrings using two
loops.forJavafor(int i=0; i<s.length(); i++) { for(int j=i; j<=s.length(); j++) { String sub = s.substring(i,j); } } -
Create another helper function
that takes a StringisPalindrome as argument and it checks whether the given string is a palindrome or not.str- When checking whether input string is palindrome or not, there are two possibilities, when the string is an odd length string and when the string is even length string.
-
Create two variables
andi to check characters on left and right side from the index where palindrome is explanding.j -
When input string is odd length string, we take the mid index
, and setmid = str.length() /2 andi=mid-1 , this is because when the string length is odd, then the mid index will be the center indexed element and we will checking whether it is palindromic string from the center.j=mid+1
For example, consider string "abcba", in this case which is 2, that is nothing but the center indexed character c. We wil be expanding around that center index, so we can setmid = 5/2 andi=1 .j=3 -
When input string is even length string, we take the mid index
, and setmid = str.length() /2 andi=mid-1 , this is because when the string length is even, there is no center indexed element for the palindrome. So, we have the check middle two characters and check whether they are same, and then expand around those two characters.j=mid
For example, consider string "abba", in this case which is 2, that is nothing but the right indexed element from the middle two elements. We wil be expanding around middle two elements, so we can setmid = 4/2 andi=1 .j=2 -
Once we have set
andi variables, then check whether character at ith index and jth index are same or not, if they are same then decrementj and incrementi to continue checking other characters in the string.j
If any of the characters on left and right are not same return otherwise returnfalse at the end.true
-
We will call this
for all substrings, and keep track of longest palindrome.isPalindrome - Finally return the longest palindrome substring found.
public class LongestPalindrome {
/* brute force approach*/
static String bruteForceApproach(String s) {
String longestPalindrome ="";
for(int i=0; i< s.length(); i++) {
for(int j=i; j<=s.length(); j++) { // we are doing j<=str.length() because substring method we are using below endIndex is exclusive
String sub = s.substring(i,j);
if(isPalindrome(sub) && sub.length()>longestPalindrome.length()) {
longestPalindrome = sub;
}
}
}
return longestPalindrome;
}
static boolean isPalindrome(String str) {
if(str == null || str.length() ==0) {
return false;
}
if(str.length() ==1) { // if the string length is 1, it is a palindrome
return true;
}
int i=0;
int j=0;
int length = str.length();
if(length % 2 == 0){ // when string length is even, for example "abba" it's a palindrome with no center
int mid = length /2; // for "abba" mid will become 2, so we should set i=1 and j=2 (i.e. b b)
// then, we can check remaining characters by moving i and j to left side and right side
// of the string respectively
j=mid;
i=mid-1;
} else { // when string length is odd, for example "abcba" it's a palindrome with c as center
int mid = length /2; // for "abcba" mid will become 2, that is already center letter c
// so we should set i=1 and j=3 (i.e. b b)
// then, we can check remaining characters by moving i and j to left side and right side
// of the string respectively
j= mid+1;
i = mid-1;
}
while (i>=0 && j<str.length()){
if(str.charAt(i) == str.charAt(j)) {
i--;
j++;
} else {
return false;
}
}
return true;
}
}
Complexity Analysis:
Time complexity: Above code runs in O(n3) time where nfor
Space complexity: O(n) as we are creating substrings, and at given point of time we only have one substring.
Solution 2 - expand around center
In this approach, what we are going to do is, from every index in the string, we try to expand to the left and to the right and check whether the characters on both sides are same or not.
-
Create a helper method
that takes parameters input stringexpandAroundCenterHelper , ints and intl left and right indexes to expand around.r-
In the implementation of this method, create a variable
to keep track maximum length palindrome found so far.maxPalindrome -
We will then try to expand the palindromic substring using left and right indexes
andl .r -
While
andl within the boundararies of input string's length, check character atr th index andl th indexes are same, that means we have found a palindrome, check the current length of palindrome usingr (+1 is because the indexes starts with 0) and keep updating the variabler-l+1 if a maximum length palindrome found.maxPalindrome -
If a palindrome substring is found, then decrement
and incrementl and keep continuing as long as left and right indexes characters are same.r
-
In the implementation of this method, create a variable
-
Now, call the helper method created above for both odd length palindromes and even length palindromes,
by supplying left and right indexes as
for odd length palindromes, theni, i for even length palindromes. Then, keep track of which palindrome is the largest one out of even / odd length palindromes returned.i, i+1
l= i;
r= i;
l= i;
r= i+1;
For example, when you expand around center for input string "babad", it will produce below output.
Below diagram only shows odd length palindromes, but the logic for even length palindromes is same,
expect you start with two characters from indexes ii+1
public class LongestPalindrome {
/* expand around center*/
static String expandAroundCenter(String s) {
String maxPalindrome = "";
for (int i = 0; i < s.length(); i++) {
// this will check only odd length palindromes, because l and r pointing to same index i
String maxPalindromeOdd = expandAroundCenterHelper(s, i, i);
// since we have checked odd length palindromes above, we will repeat the same process for even length palindromes
String maxPalindromeEven = expandAroundCenterHelper(s, i, i + 1);
if (maxPalindromeOdd.length() > maxPalindrome.length()) {
maxPalindrome = maxPalindromeOdd;
}
if (maxPalindromeEven.length() > maxPalindrome.length()) {
maxPalindrome = maxPalindromeEven;
}
}
return maxPalindrome;
}
static String expandAroundCenterHelper(String s, int l, int r) {
String maxPalindrome = "";
while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {
if (r - l + 1 > maxPalindrome.length()) {
maxPalindrome = s.substring(l, r + 1);
}
l--;
r++;
}
return maxPalindrome;
}
}
Complexity Analysis:
Time complexity: Above code runs in O(n2) time where n
Space complexity: O(n), since we have to keep track of maximum length palindrome substring.
Above implementations source code can be found at