Find the longest sub-string which is prefix, suffix and also present inside the string

• Difficulty Level : Hard
• Last Updated : 05 Aug, 2021

Given string str. The task is to find the longest sub-string which is a prefix, a suffix, and a sub-string of the given string, str. If no such string exists then print -1.
Examples:

Input: str = “fixprefixsuffix”
Output: fix
“fix” is a prefix, suffix and present inside in the string too.
Input: str = “aaaa”
“aa” is a prefix, suffix and present inside the string.

Approach: Let us calculate the longest prefix suffix for all prefixes of string. longest prefix suffix lps[i] is maximal length of prefix that also is suffix of substring [0…i]. More about the longest prefix suffix you can see in a description of kmp algorithm.
The first possible answer is a prefix of length lps[n-1]. If lps[n-1] = 0, there is no solution. For checking the first possible answer you should iterate over lps[i]. If at least one of them equal to lps[n-1] (but not n-1th, of course) – you found the answer. The second possible answer is a prefix of length lps[lps[n-1]-1]. If lps[lps[n-1]-1] = 0, you also have no solution. Otherwise, you can be sure that the answer already found. This substring is a prefix and a suffix of our string. Also, it is a suffix of a prefix with length lps[n-1] that places inside of all strings. This solution works in O(n).
Below is the implementation of the above approach:

C++

 // C++ implementation of the approach#include using namespace std; // Function to find longest prefix suffixvector compute_lps(string s){    int n = s.size();     // To store longest prefix suffix    vector lps(n);     // Length of the previous    // longest prefix suffix    int len = 0;     // lps is always 0    lps = 0;    int i = 1;     // Loop calculates lps[i] for i = 1 to n - 1    while (i < n) {        if (s[i] == s[len]) {            len++;            lps[i] = len;            i++;        }         // (pat[i] != pat[len])        else {            if (len != 0)                len = lps[len - 1];            // Also, note that we do not increment            // i here             // If len = 0            else {                lps[i] = 0;                i++;            }        }    }     return lps;} // Function to find the longest substring// which is prefix as well as a// sub-string of s[1...n-2]void Longestsubstring(string s){    // Find longest prefix suffix    vector lps = compute_lps(s);    int n = s.size();     // If lps of n-1 is zero    if (lps[n - 1] == 0) {        cout << -1;        return;    }     for (int i = 0; i < n - 1; i++) {         // At any position lps[i] equals to lps[n - 1]        if (lps[i] == lps[n - 1]) {            cout << s.substr(0, lps[i]);            return;        }    }     // If answer is not possible    if (lps[lps[n - 1] - 1] == 0)        cout << -1;    else        cout << s.substr(0, lps[lps[n - 1] - 1]);} // Driver codeint main(){    string s = "fixprefixsuffix";     // function call    Longestsubstring(s);     return 0;}

Java

 // Java implementation of the approachclass GFG{    // Function to find longest prefix suffix    static int [] compute_lps(String s)    {        int n = s.length();             // To store longest prefix suffix        int [] lps = new int [n];             // Length of the previous        // longest prefix suffix        int len = 0;             // lps is always 0        lps = 0;        int i = 1;             // Loop calculates lps[i] for i = 1 to n - 1        while (i < n)        {            if (s.charAt(i) == s.charAt(len))            {                len++;                lps[i] = len;                i++;            }                 // (pat[i] != pat[len])            else            {                if (len != 0)                    len = lps[len - 1];                // Also, note that we do not increment                // i here                     // If len = 0                else                {                    lps[i] = 0;                    i++;                }            }        }             return lps;    }         // Function to find the longest substring    // which is prefix as well as a    // sub-string of s[1...n-2]    static void Longestsubstring(String s)    {        // Find longest prefix suffix        int [] lps = compute_lps(s);        int n = s.length();             // If lps of n-1 is zero        if (lps[n - 1] == 0)        {            System.out.println(-1);            return;        }             for (int i = 0; i < n - 1; i++)        {                 // At any position lps[i] equals to lps[n - 1]            if (lps[i] == lps[n - 1])            {                System.out.println(s.substring(0, lps[i]));                return;            }        }             // If answer is not possible        if (lps[lps[n - 1] - 1] == 0)            System.out.println(-1);        else            System.out.println(s.substring(0, lps[lps[n - 1] - 1]));    }         // Driver code    public static void main (String [] args)    {        String s = "fixprefixsuffix";             // function call        Longestsubstring(s);         }} // This code is contributed by ihritik

Python3

 # Python3 implementation of the approach # Function to find longest prefix suffixdef compute_lps(s):     n = len(s)     # To store longest prefix suffix    lps = [0 for i in range(n)]     # Length of the previous    # longest prefix suffix    Len = 0     # lps is always 0    lps = 0    i = 1     # Loop calculates lps[i] for i = 1 to n - 1    while (i < n):        if (s[i] == s[Len]):            Len += 1            lps[i] = Len            i += 1         # (pat[i] != pat[Len])        else:            if (Len != 0):                Len = lps[Len - 1]            # Also, note that we do not increment            # i here             # If Len = 0            else:                lps[i] = 0                i += 1                  return lps # Function to find the longest substring# which is prefix as well as a# sub-of s[1...n-2]def Longestsubstring(s):     # Find longest prefix suffix    lps = compute_lps(s)    n = len(s)     # If lps of n-1 is zero    if (lps[n - 1] == 0):        print(-1)        exit()         for i in range(0,n - 1):         # At any position lps[i] equals to lps[n - 1]        if (lps[i] == lps[n - 1]):            print(s[0:lps[i]])            exit()     # If answer is not possible    if (lps[lps[n - 1] - 1] == 0):        print(-1)    else:        print(s[0:lps[lps[n - 1] - 1]]) # Driver code s = "fixprefixsuffix" # function callLongestsubstring(s) # This code is contributed by mohit kumar

C#

 // C# implementation of the approachusing System; class GFG{    // Function to find longest prefix suffix    static int [] compute_lps(string s)    {        int n = s.Length;             // To store longest prefix suffix        int [] lps = new int [n];             // Length of the previous        // longest prefix suffix        int len = 0;             // lps is always 0        lps = 0;        int i = 1;             // Loop calculates lps[i] for i = 1 to n - 1        while (i < n)        {            if (s[i] == s[len])            {                len++;                lps[i] = len;                i++;            }                 // (pat[i] != pat[len])            else            {                if (len != 0)                    len = lps[len - 1];                // Also, note that we do not increment                // i here                     // If len = 0                else                {                    lps[i] = 0;                    i++;                }            }        }             return lps;    }         // Function to find the longest substring    // which is prefix as well as a    // sub-string of s[1...n-2]    static void Longestsubstring(string s)    {        // Find longest prefix suffix        int [] lps = compute_lps(s);        int n = s.Length;             // If lps of n-1 is zero        if (lps[n - 1] == 0)        {            Console.WriteLine(-1);            return;        }             for (int i = 0; i < n - 1; i++)        {                 // At any position lps[i] equals to lps[n - 1]            if (lps[i] == lps[n - 1])            {                Console.WriteLine(s.Substring(0, lps[i]));                return;            }        }             // If answer is not possible        if (lps[lps[n - 1] - 1] == 0)            Console.WriteLine(-1);        else            Console.WriteLine(s.Substring(0, lps[lps[n - 1] - 1]));    }         // Driver code    public static void Main ()    {        string s = "fixprefixsuffix";             // function call        Longestsubstring(s);         }} // This code is contributed by ihritik



Javascript


Output:
fix

Time Complexity : O(N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up