Longest Palindromic Substring | Set 2

Given a string, find the longest substring which is palindrome. For example, if the given string is “forgeeksskeegfor”, the output should be “geeksskeeg”.

We have discussed dynamic programming solution in the previous post. The time complexity of the Dynamic Programming based solution is O(n^2) and it requires O(n^2) extra space. We can find the longest palindrome substring in (n^2) time with O(1) extra space. The idea is to generate all even length and odd length palindromes and keep track of the longest palindrome seen so far.

Step to generate odd length palindrome:
Fix a centre and expand in both directions for longer palindromes.

Step to generate even length palindrome
Fix two centre ( low and high ) and expand in both directions for longer palindromes.

C/C++

// A O(n^2) time and O(1) space program to find the longest palindromic substring
#include <stdio.h>
#include <string.h>

// A utility function to print a substring str[low..high]
void printSubStr(char* str, int low, int high)
{
    for( int i = low; i <= high; ++i )
        printf("%c", str[i]);
}

// This function prints the longest palindrome substring (LPS)
// of str[]. It also returns the length of the longest palindrome
int longestPalSubstr(char *str)
{
    int maxLength = 1;  // The result (length of LPS)

    int start = 0;
    int len = strlen(str);

    int low, high;

    // One by one consider every character as center point of 
    // even and length palindromes
    for (int i = 1; i < len; ++i)
    {
        // Find the longest even length palindrome with center points
        // as i-1 and i.  
        low = i - 1;
        high = i;
        while (low >= 0 && high < len && str[low] == str[high])
        {
            if (high - low + 1 > maxLength)
            {
                start = low;
                maxLength = high - low + 1;
            }
            --low;
            ++high;
        }

        // Find the longest odd length palindrome with center 
        // point as i
        low = i - 1;
        high = i + 1;
        while (low >= 0 && high < len && str[low] == str[high])
        {
            if (high - low + 1 > maxLength)
            {
                start = low;
                maxLength = high - low + 1;
            }
            --low;
            ++high;
        }
    }

    printf("Longest palindrome substring is: ");
    printSubStr(str, start, start + maxLength - 1);

    return maxLength;
}

// Driver program to test above functions
int main()
{
    char str[] = "forgeeksskeegfor";
    printf("\nLength is: %d\n", longestPalSubstr( str ) );
    return 0;
}

Python


# A O(n^2) time and O(1) space program to find the 
#longest palindromic substring

# This function prints the longest palindrome substring (LPS)
# of str[]. It also returns the length of the longest palindrome
def longestPalSubstr(string):
    maxLength = 1

    start = 0
    length = len(string)

    low = 0
    high = 0

    # One by one consider every character as center point of 
    # even and length palindromes
    for i in xrange(1, length):
        # Find the longest even length palindrome with center
	# points as i-1 and i.
        low = i - 1
        high = i
        while low >= 0 and high < length and string[low] == string[high]:
            if high - low + 1 > maxLength:
                start = low
                maxLength = high - low + 1
            low -= 1
            high += 1

        # Find the longest odd length palindrome with center 
        # point as i
        low = i - 1
        high = i + 1
        while low >= 0 and high < length and string[low] == string[high]:
            if high - low + 1 > maxLength:
                start = low
                maxLength = high - low + 1
            low -= 1
            high += 1

    print "Longest palindrome substring is:",
    print string[start:start + maxLength]

    return maxLength

# Driver program to test above functions
string = "forgeeksskeegfor"
print "Length is: " + str(longestPalSubstr(string))

# This code is contributed by BHAVYA JAIN

Output:

Longest palindrome substring is: geeksskeeg
Length is: 10

Time complexity: O ( n^2 ) where n is the length of input string.
Auxiliary Space: O ( 1 )

We will soon be adding more optimized method as separate post.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.







Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the link here.

  • Byron Formwalt

    In Ruby, this can be accomplished writing less code.

    #!/usr/bin/env ruby

    class String
    def largest_palindrome
    s1 = self.split("")
    s2 = s1.reverse
    p = ""
    (s2.length).times do |i|
    # Determine the max length of aligned letters.
    c = s1.each_with_index.collect do |v1,j|
    v1 == s2[j] ? v1 : "_"
    end
    c = c.join.split("_")
    n = c.collect{|e| e.reverse == e ? e.length : 0}.max || 0
    p = c.find{|e| e.length == n} if n > p.length
    s2.rotate!
    end
    p
    end
    end

    s = ["","a","aa","rabaraa","forgeeksskeegfor","habacdedcabag",
    "abacdgfdcaba",
    "ABCBAHELLOHOWRACECARAREYOUIAMAIDOINGGOOD"]

    s.each do |s|
    puts "Largest Palindrome: "#{s.largest_palindrome}""
    end

    Outputs:

    Largest Palindrome: “”
    Largest Palindrome: “a”
    Largest Palindrome: “aa”
    Largest Palindrome: “ara”
    Largest Palindrome: “geeksskeeg”
    Largest Palindrome: “abacdedcaba”
    Largest Palindrome: “aba”
    Largest Palindrome: “RACECAR”

  • mccullum

    the following does the job in O(n)

    #include

    int func(char *str)

    {

    int i=0,length=0,mlength=0,j;

    while(*(str+i)!=”)

    {

    if(i!=0 && (*(str+i-1)==*(str+i+1)))

    {

    length=1;

    j=1;

    while(*(str+i+j)==*(str+i-j))

    {

    j++;

    length+=2;

    }

    i=i+j;

    if(length>mlength)

    mlength=length;

    }

    else if(*(str+i) == *(str+i+1))

    {

    length=0;

    j=i;

    i++;

    while(j>=0 && *(str+j)==*(str+i))

    {

    j–;

    i++;

    length=length+2;

    }

    if(length>mlength)

    mlength=length;

    }

    else

    i++;

    }

    return mlength;

    }

    int main()

    {

    char str[80];

    int lps;

    scanf(“%s”,str);

    lps=func(str);

    printf(“%dn”,lps);

    return 0;

    }

  • shashi

    inside while condition:
    high < len,
    this will never be true.??
    m I missing something here…

    • atreyee

      it is len not low i guess u have mistaken there

      • shashi

        ohh yes…

  • shashi

    inside while condition:
    high < len,
    this will never be true.??
    m I missing something here…

  • sukisukimo

    /*

    * Program to find the longest palindrome
    * The algo time complexity is O(n^2) and space complexity is O(1)

    */

    static String getBigPalindrome(String str)

    {

    int i = 0, j = 0, tempi = 0;

    int maxLen = 0, currentLen = 0;

    String maxpalin = null;

    String currentpalin = null;

    char[] carr = str.toCharArray();

    for (i = 0; i i; j–)

    {

    if (carr[i] == carr[j])

    {

    /*

    * if checks — whenever we encounter the same char, check the common mid char j – i == 1(for palindrome

    * like “geeksskeeg”)

    * or 2 common mid chars j – i == 2(for palindrome like “civic”)

    * else increase the value of i

    */

    if (j – i == 1 || j – i == 2)

    {

    currentpalin = str.substring(tempi, i + (i – (tempi – 1)) + j – i);

    currentLen = currentpalin.length();

    /*

    * check if the previous palindrome have longer length

    */

    if (maxLen < currentLen)

    {

    maxpalin = currentpalin;

    maxLen = currentLen;

    }

    }

    i++;

    }

    /*

    * else the next char is not the same, the restore the value of i

    */

    else

    {

    i = tempi;

    }

    }

    }

    return maxpalin;

    }

  • shek8034

    O(N) Solution : Manacher’s Algorithm

  • shek8034
  • ap

    In reply to a previous query, I have tried to write an O(n) time complexity code. Let me know if it works out for all the desired test cases.

     
    /* Paste your code here (You may delete these lines if not writing code) */
    #include<stdio.h>
    #include<string.h>
    int main()
    {
    
    	char s[50]="forgeeksskeegfor";
    
    	int k,i,j,c=0;
    	int len=strlen(s);
    
    	
    	for(i=0,j=len-1;i<j;i++,j--)
    	{
    
    		if(s[i]==s[j])
    		{
    			c=c+2;
    		}
    		else
    		c=0;
    	}
    	if(len==1)
    	printf("Pallindrome of 1");
    	else if(c==0)
    	printf("No palindrome");
    	else if(i==j)
    	printf("length is %d",c+1);
    	else
    	printf("%d",c);
    
    return 0;
    }
     
    • ap

      My bad…I got the question wrong!

       
      /* Paste your code here (You may delete these lines if not writing code) */
       
  • abhishek08aug

    Intelligent 😀

  • koolkeshaw

    public class longestPalindromicSubString
    {

    String str="geeksforrofsekabcdefedcba";
    public static void main(String[] args)
    {
    longestPalindromicSubString lpstring=new longestPalindromicSubString();
    String result=lpstring.calLongestPalindrome();
    System.out.println(" "+result);

    }
    String calLongestPalindrome()
    {
    int lPLength=0;
    String lSubPalin=new String();
    int oLength=1;
    int i=1;
    int lLimit,uLimit;
    for(;i<this.str.length()-1;i++)
    {
    lLimit=i-1;
    uLimit=i+1;
    Character ch=str.charAt(i);
    StringBuffer temp=new StringBuffer(ch.toString());
    while(this.str.charAt(lLimit)==this.str.charAt(uLimit))
    {
    oLength+=2;
    temp.append(this.str.charAt(uLimit));
    temp.insert(0,this.str.charAt(uLimit));
    lLimit–;
    uLimit++;
    if(uLimit==this.str.length()||lLimit==-1)
    break;
    }
    if(oLength>lPLength)
    {
    lPLength=oLength;
    lSubPalin=new String(temp);
    }
    oLength=1;
    temp=null;
    }
    int eLength=0;
    for(i=1 ;i<this.str.length()-1;i++)
    {
    StringBuffer temp=new StringBuffer();
    lLimit=i;
    uLimit=i+1;
    while(this.str.charAt(lLimit)==this.str.charAt(uLimit))
    {
    eLength+=2;
    temp.append(this.str.charAt(uLimit));
    temp.insert(0,this.str.charAt(lLimit));
    lLimit–;
    uLimit++;
    if(uLimit==this.str.length()||lLimit==-1)
    break;
    }
    if(eLength>lPLength)
    {
    lPLength=eLength;
    lSubPalin=new String(temp);
    }
    eLength=0;
    temp=null;
    }
    return lSubPalin ;
    }
    }

    • koolkeshaw

      Please inform me of any test case where the above code fails……..

      • coderAce

        Let me ask you something? 90 percentage of code posted by commenteers here either have build errors or do not follow the correct strategy. So given all that, don’t you think it is extremely rude to simply paste a piece of code and follow up by ordering others to let you know if any test cases fail??

        People come here to prepare and not test some one’s code who doesn’t even bother to provide a little explanation about the algorithm he is using.

        If any test case fails, then probably it’s because your strategy was wrong. So next time paste the strategy. Don’t just paste a piece of code and order people to let you know if any tet case fails!

  • Amit

    Can we make 2 suffix tree one with given string and one with reverse of string and while traversing the suffix tree when we are getting common path then find the size of that suffix tree and print the maximum size whatever we get.

    • Amateur_coder

      I think what u are trying to say is its like when u create a tree with the elemnts in reverse order and find out the LONGEST_COMMON_sequence of the 2 strings…..

       
      /* Paste your code here (You may delete these lines if not writing code) */
       
      • Amateur_coder

        sorry…it was a wrong response.didnt read d question properly…

  • Amit
     
    /* Paste your code here (You may delete these lines if not writing code) */
    @geeksforgeeks/Venki:-
    Can we make 2 suffix tree one with given string and one with reverse of string and while traversing the suffix tree when we are getting common path then find the size of that suffix tree and print the maximum size whatever we get. 
     
  • invictus

    This can be done in O(n)complexity and O(n) extra space using Mancher’s Algorithm.

     
    /* Paste your code here (You may delete these lines if not writing code) */
     
  • @Geeksforgeeks can you post O(n) approach for the same ?

     
    /* Paste your code here (You may delete these lines if not writing code) */
     
    • jj

      see leetcode.com fr d same

       
      /* Paste your code here (You may delete these lines if not writing code) */
       
  • Rainer

    sorry,
    but I messed up the code, should be:

     
        for (int i = 0; i < len; ++i)
            low = i - 1;
            while (low >= 0 
     

    I think the condition for while will always be false, but probably I simply don’t understand. Can you please tell me, if the while loop will be executed if i = -1?

    thanks again
    Rainer

    • Aashish

      The while will not execute for i = 0. Observe that while loop is true for higher values of “i”.

      We have updated the post. Keep it up!

  • Rainer

    Hello,
    i don’t know C but like your website and try to translate your examples to other languages.
    Could you please explain how the while loops are supposed to work?

    for (int i = 0; i = 0 && …


    low = i – 1;
    while (low >= 0 …

    i do not understand how either of the while loops will be executed.

    Thank you for your help & your great website
    Rainer

  • theredkhan

    Or perhaps the input string is not meant to a palindrome in itself…

  • theredkhan

    “forgeeksskeegfor” is not a palindrome!!

    It should surely be “forgeeksskeegrof”.

  • anirudh

    gud code

     
    /* Paste your code here (You may delete these lines if not writing code) */
     
    • naveen

      the condition in the for loop can be optimized to the following:
      for(i=1;i<len-maxlength+1;i++)
      Explaination: If we found a palindrome of length 'n' then we need not to search for any palindrome of length = n.