Skip to content
Related Articles
Get the best out of our app
GeeksforGeeks App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Longest prefix which is also suffix

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

Given a string s, find the length of the longest prefix, which is also a suffix. The prefix and suffix should not overlap.

Examples: 

Input : aabcdaabc
Output : 4
The string "aabc" is the longest
prefix which is also suffix.

Input : abcab
Output : 2

Input : aaaa
Output : 2
Recommended Practice

Simple Solution: Since overlapping prefixes and suffixes is not allowed, we break the string from the middle and start matching left and right strings. If they are equal return size of one string, else they try for shorter lengths on both sides.
Below is a solution to the above approach!

C++




// CPP program to find length of the
// longest prefix which is also suffix
#include <bits/stdc++.h>
using namespace std;
 
// Function to find largest prefix
// which is also a suffix
int largest_prefix_suffix(const std::string
                                      &str)
{
   
  int n = str.length();
   
  // if n is less than 2
  if(n < 2) {
    return 0;
  }
 
  int len = 0;
  int i = 1;
   
  // Iterate i till n
  while(i < n)
  {
     
    // If str[i] is equal to
    // str[len]
    if(str[i] == str[len])
    {
      ++len;
      ++i;
    }
    else
    {
      i = i - len + 1;
      len = 0;
    }
  }
   
  // Return len
  return len>n/2? len/2:len;
 
}
 
// Driver code
int main()
{
     
  string s = "blablabla";
 
  // Function Call
  cout << largest_prefix_suffix(s);
  return 0;
}

C




#include <stdio.h>
#include <string.h>
 
int largest_prefix_suffix(const char* str)
{
    int n = strlen(str);
 
    // If n is less than 2
    if (n < 2) {
        return 0;
    }
 
    int len = 0;
    int i = 1;
 
    // Iterate i till n
    while (i < n) {
        // If str[i] is equal to str[len]
        if (str[i] == str[len]) {
            ++len;
            ++i;
        }
        else {
            i = i - len + 1;
            len = 0;
        }
    }
 
    // Return len
    return len > n / 2 ? len / 2 : len;
}
 
int main()
{
    const char* s = "blablabla";
 
    // Function Call
    printf("%d\n", largest_prefix_suffix(s));
 
    return 0;
}

Java




// Java program to find length of the longest
// prefix which is also suffix
class GFG
{
     
   // Function to find largest prefix
   // which is also a suffix
   static int longestPrefixSuffix(String s)
   {
      int n = s.length();
 
      // If n is less than 2
      if(n < 2) {
          return 0;
      }
 
      int len = 0;
      int i = (n + 1)/2;
 
      // Iterate i till n
      while(i < n)
      {
 
        // If s.charAt(i) is equal to
        // s.charAt(len)
        if(s.charAt(i) == s.charAt(len))
        {
          ++len;
          ++i;
        }
        else
        {
          i = i - len + 1;
          len = 0;
        }
      }
 
      // Return len
      return len;
 
  }
     
    // Driver code
  public static void main (String[] args)
  {
    String s = "abcaabc";
    System.out.println(longestPrefixSuffix(s));
  }
}
 
// This code is contributed by Anant Agarwal.

Python3




# Python3 program to find length
# of the longest prefix which
# is also suffix
def longestPrefixSuffix(s) :
    n = len(s)
     
    for res in range(n // 2, 0, -1) :
         
        # Check for shorter lengths
        # of first half.
        prefix = s[0: res]
        suffix = s[n - res: n]
         
        if (prefix == suffix) :
            return res
             
 
    # if no prefix and suffix match
    # occurs
    return 0
     
# Driver Code
if __name__ == "__main__":
    s = "blablabla"
    print(longestPrefixSuffix(s))
 
# This code is contributed by Nikita Tiwari.

Javascript




<script>
 
// JavaScript program to find length of the longest
// prefix which is also suffix
 
   // Function to find largest prefix
   // which is also a suffix
   function longestPrefixSuffix(s)
   {
      var n = s.length;
 
      // If n is less than 2
      if(n < 2) {
          return 0;
      }
 
      var len = 0;
      var i = (n + 1)/2;
 
      // Iterate i till n
      while(i < n)
      {
 
        // If s[i] is equal to
        // s[len]
        if(s[i] == s[len])
        {
          ++len;
          ++i;
        }
        else
        {
          i = i - len + 1;
          len = 0;
        }
      }
 
      // Return len
      return len;
 
  }
     
// Driver code
var s = "blablabla";
document.write(longestPrefixSuffix(s));
 
// This code contributed by shikhasingrajput
 
</script>

C#




// C# program to find length of the longest
// prefix which is also suffix
using System;
 
class GFG
{
     
    // Function to find largest prefix
    // which is also a suffix
    static int longestPrefixSuffix(String s)
    {
        int n = s.Length;
     
        // if n is less than 2
        if(n < 2) {
          return 0;
        }
 
        int len = 0;
        int i = (n + 1)/2;
 
        // Iterate i till n
        while(i < n)
        {
 
          // If str[i] is equal to
          // str[len]
          if(str[i] == str[len])
          {
            ++len;
            ++i;
          }
          else
          {
            i = i - len + 1;
            len = 0;
          }
        }
 
        // Return len
        return len;
    }
     
    // Driver code
    public static void Main ()
    {
        String s = "blablabla";
         
        Console.WriteLine(longestPrefixSuffix(s));
    }
}
 
// This code is contributed by vt_m.

Output: 

3

 

Time Complexity: O(n)
Auxiliary Space: O(1)

Efficient Solution: The idea is to use the preprocessing algorithm KMP search. In the preprocessing algorithm, we build lps array which stores the following values.

lps[i] = the longest proper prefix of pat[0..i] 
which is also a suffix of pat[0..i].

C




#include <stdio.h>
#include <string.h>
 
int longestPrefixSuffix(const char* s)
{
    int n = strlen(s);
    int lps[n];
    lps[0] = 0; // lps[0] is always 0
 
    int len = 0;
    int i = (n + 1) / 2;
 
    while (i < n) {
        if (s[i] == s[len]) {
            len++;
            lps[i] = len;
            i++;
        }
        else {
            if (len != 0) {
                len = lps[len - 1];
            }
            else {
                lps[i] = 0;
                i++;
            }
        }
    }
 
    int res = lps[n - 1];
 
    return res;
}
 
int main()
{
    const char* s = "bbabbabb";
    printf("%d\n", longestPrefixSuffix(s));
    return 0;
}

C++




// Efficient CPP program to find length of
// the longest prefix which is also suffix
#include<bits/stdc++.h>
using namespace std;
 
// Returns length of the longest prefix
// which is also suffix and the two do
// not overlap. This function mainly is
// copy computeLPSArray() of in below post
int longestPrefixSuffix(string s)
{
    int n = s.length();
 
    int lps[n];
    lps[0] = 0; // lps[0] is always 0
 
    // length of the previous
    // longest prefix suffix
    int len = 0;
 
    // the loop calculates lps[i]
    // for i = 1 to n-1
    int i = (n+1)/2;
    while (i < n)
    {
        if (s[i] == s[len])
        {
            len++;
            lps[i] = len;
            i++;
        }
        else // (pat[i] != pat[len])
        {
            // This is tricky. Consider
            // the example. AAACAAAA
            // and i = 7. The idea is
            // similar to search step.
            if (len != 0)
            {
                len = lps[len-1];
 
                // Also, note that we do
                // not increment i here
            }
            else // if (len == 0)
            {
                lps[i] = 0;
                i++;
            }
        }
    }
 
    int res = lps[n-1];
 
    // Since we are looking for
    // non overlapping parts.
    return res;
}
 
// Driver program to test above function
int main()
{
    string s = "bbabbabb";
    cout << longestPrefixSuffix(s);
    return 0;
}
 
// Corrected by Nilanshu Yadav

Java




// Efficient Java program to find length of
// the longest prefix which is also suffix
 
class GFG
{
    // Returns length of the longest prefix
    // which is also suffix and the two do
    // not overlap. This function mainly is
    // copy computeLPSArray() of in below post
    // for-patterns-set-2-kmp-algorithm/
    static int longestPrefixSuffix(String s)
    {
        int n = s.length();
     
        int lps[] = new int[n];
         
        // lps[0] is always 0
        lps[0] = 0;
     
        // length of the previous
        // longest prefix suffix
        int len = 0;
     
        // the loop calculates lps[i]
        // for i = 1 to n-1
        int i = (n+1)/2;
        while (i < n)
        {
            if (s.charAt(i) == s.charAt(len))
            {
                len++;
                lps[i] = len;
                i++;
            }
             
             // (pat[i] != pat[len])
            else
            {
                // This is tricky. Consider
                // the example. AAACAAAA
                // and i = 7. The idea is
                // similar to search step.
                if (len != 0)
                {
                    len = lps[len-1];
     
                    // Also, note that we do
                    // not increment i here
                }
                 
                // if (len == 0)
                else
                {
                    lps[i] = 0;
                    i++;
                }
            }
        }
     
        int res = lps[n-1];
     
        // Since we are looking for
        // non overlapping parts.
        return res;
    }
     
    // Driver program
    public static void main (String[] args)
    {
        String s = "bbabbabb";
        System.out.println(longestPrefixSuffix(s));
    }
}
 
// This code is contributed by Anant Agarwal.
// Corrected by Nilanshu Yadav

Python3




# Efficient Python 3 program
# to find length of
# the longest prefix
# which is also suffix
 
# Returns length of the longest prefix
# which is also suffix and the two do
# not overlap. This function mainly is
# copy computeLPSArray() of in below post
def longestPrefixSuffix(s) :
    n = len(s)
    lps = [0] * n   # lps[0] is always 0
  
    # length of the previous
    # longest prefix suffix
    l = 0
     
    # the loop calculates lps[i]
    # for i = 1 to n-1
    i = (n+1)//2;
    while (i < n) :
        if (s[i] == s[l]) :
            l = l + 1
            lps[i] = l
            i = i + 1
         
        else :
 
            # (pat[i] != pat[len])
            # This is tricky. Consider
            # the example. AAACAAAA
            # and i = 7. The idea is
            # similar to search step.
            if (l != 0) :
                l = lps[l-1]
  
                # Also, note that we do
                # not increment i here
             
            else :
 
                # if (len == 0)
                lps[i] = 0
                i = i + 1
  
    res = lps[n-1]
  
    # Since we are looking for
    # non overlapping parts.
    return res;
         
  
# Driver program to test above function
s = "bbabbabb"
print(longestPrefixSuffix(s))
 
 
# This code is contributed
# by Nikita Tiwari.
#Corrected by Nilanshu Yadav

Javascript




<script>
 
// Efficient javascript program to find length of
// the longest prefix which is also suffix{
// Returns length of the longest prefix
// which is also suffix and the two do
// not overlap. This function mainly is
// copy computeLPSArray() of in below post
// for-patterns-set-2-kmp-algorithm/
function longestPrefixSuffix(s)
{
    var n = s.length;
 
    var lps = Array.from({length: n}, (_, i) => 0);
     
    // lps[0] is always 0
    lps[0] = 0;
 
    // length of the previous
    // longest prefix suffix
    var len = 0;
 
    // the loop calculates lps[i]
    // for i = 1 to n-1
    var i = 1;
    while (i < n)
    {
        if (s.charAt(i) == s.charAt(len))
        {
            len++;
            lps[i] = len;
            i++;
        }
         
         // (pat[i] != pat[len])
        else
        {
            // This is tricky. Consider
            // the example. AAACAAAA
            // and i = 7. The idea is
            // similar to search step.
            if (len != 0)
            {
                len = lps[len-1];
 
                // Also, note that we do
                // not increment i here
            }
             
            // if (len == 0)
            else
            {
                lps[i] = 0;
                i++;
            }
        }
    }
 
    var res = lps[n-1];
 
    // Since we are looking for
    // non overlapping parts.
    return (res > n/2)? n/2 : res;
}
 
// Driver program
var s = "abcab";
document.write(longestPrefixSuffix(s));
 
 
// This code is contributed by 29AjayKumar
 
 
</script>

C#




// Efficient C# program to find length of
// the longest prefix which is also suffix
using System;
 
class GFG {
     
    // Returns length of the longest prefix
    // which is also suffix and the two do
    // not overlap. This function mainly is
    // copy computeLPSArray() of in below post
    // for-patterns-set-2-kmp-algorithm/
    static int longestPrefixSuffix(string s)
    {
        int n = s.Length;
     
        int []lps = new int[n];
         
        // lps[0] is always 0
        lps[0] = 0;
     
        // length of the previous
        // longest prefix suffix
        int len = 0;
     
        // the loop calculates lps[i]
        // for i = 1 to n-1
        int i = 1;
        while (i < n)
        {
            if (s[i] == s[len])
            {
                len++;
                lps[i] = len;
                i++;
            }
             
            // (pat[i] != pat[len])
            else
            {
                 
                // This is tricky. Consider
                // the example. AAACAAAA
                // and i = 7. The idea is
                // similar to search step.
                if (len != 0)
                {
                    len = lps[len-1];
     
                    // Also, note that we do
                    // not increment i here
                }
                 
                // if (len == 0)
                else
                {
                    lps[i] = 0;
                    i++;
                }
            }
        }
     
        int res = lps[n-1];
     
        // Since we are looking for
        // non overlapping parts.
        return (res > n/2) ? n/2 : res;
    }
     
    // Driver program
    public static void Main ()
    {
        string s = "abcab";
         
        Console.WriteLine(longestPrefixSuffix(s));
    }
}
 
// This code is contributed by vt_m.

PHP




<?php
// Efficient PHP program to find length of
// the longest prefix which is also suffix
 
// Returns length of the longest prefix
// which is also suffix and the two do
// not overlap. This function mainly is
// copy computeLPSArray() of in below post
function longestPrefixSuffix($s)
{
    $n = strlen($s);
 
    $lps[$n] = NULL;
     
    // lps[0] is always 0
    $lps[0] = 0;
 
    // length of the previous
    // longest prefix suffix
    $len = 0;
 
    // the loop calculates lps[i]
    // for i = 1 to n-1
    $i = 1;
    while ($i < $n)
    {
        if ($s[$i] == $s[$len])
        {
            $len++;
            $lps[$i] = $len;
            $i++;
        }
         
        // (pat[i] != pat[len])
        else
        {
             
            // This is tricky. Consider
            // the example. AAACAAAA
            // and i = 7. The idea is
            // similar to search step.
            if ($len != 0)
            {
                $len = $lps[$len-1];
 
                // Also, note that we do
                // not increment i here
            }
             
            // if (len == 0)
            else
            {
                $lps[$i] = 0;
                $i++;
            }
        }
    }
 
    $res = $lps[$n-1];
 
    // Since we are looking for
    // non overlapping parts.
    return ($res > $n/2)? $n/2 : $res;
}
 
    // Driver Code
    $s = "abcab";
    echo longestPrefixSuffix($s);
 
// This code is contributed by nitin mittal
?>

Output: 

2

 

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

Please refer computeLPSArray() of KMP search for an explanation.
 

Solution using RegEx: 

C++




#include <iostream>
#include <regex> // Required for std::regex and std::smatch
 
int main() {
    std::string s = "ABCABCABCABCABC"; // Example input
 
    std::regex regex("^(\\w*).*\\1$"); // Define the regular expression
    std::smatch match; // Define a match object to store the matched string
 
    if (std::regex_search(s, match, regex)) { // Search for a match in the string
        std::cout << match.str(1).length() << std::endl; // Output the length of the first capturing group
    }
 
    return 0;
}

Java




import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class GFG {
  public static void main(String[] args) {
    String s = "ABCABCABCABCABC"; // Example input
 
    String regex = "^(\\w*).*\\1$";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(s);
 
    if (matcher.find()) {
      System.out.println(matcher.group(1).length());
    }
  }
}

Python3




# Python code to find length of the longest
# prefix which is also suffix
import re
 
s = "ABCABCABCABCABC" # Example input
 
print(len(re.findall(r'^(\w*).*\1$',s)[0]))

Javascript




const s = "ABCABCABCABCABC"; // Example input
 
const regex = new RegExp(`^(\\w*).*\\1$`);
const match = s.match(regex);
 
console.log(match[1].length);
 
// THIS CODE IS CONTRIBUTED BY CHANDAN AGARWAL

Output: 

6

 

The time and space complexity of this program depend on the size of the input string and the complexity of the regular expression.

Assuming the input string has length n, the time complexity of std::regex_search function is typically O(n) on most modern regex engines, but can be worse in some cases. The time complexity of the std::string::length() function is O(1). Therefore, the overall time complexity of this program is O(n).

The space complexity of the program is mainly determined by the size of the match object std::smatch. The space required by std::smatch depends on the number of captured subgroups in the regular expression and the size of the input string. In this case, the regular expression has one capturing group, so the space complexity is proportional to the size of the input string. Therefore, the space complexity of the program is O(n).

Efficient Solution: The idea is to traverse the suffix in reverse order and try to find a match in first half of the string (possible prefix). Here we take advantage of the property of a prefix substring – when traversed in reverse order, the prefix substring’s last character will always terminate at the string’s beginning.

Please note that we search for the prefix in the first half of the string alone because of the constraint given in the problem that the prefix and suffix are non-overlapping.

Algorithm :

        1. Maintain two pointers –  one which starts at the end of string(for suffix) and one which starts at the middle of string(for prefix)

        2. Keep on decrementing both the pointers provided they match and the prefix pointer is not exhausted( >0) .

        3. When a mismatch occurs, reset the suffix pointer back to end of string and repeat step 2.

        4. When prefix pointer reaches ‘-1’ (i.e. string is exhausted) the longest common suffix/prefix will be the substring from suffix pointer

            to end of the string.  Return the length of this substring. 

Implementation:

C++




#include<iostream>
#include<string>
using namespace std;
 
int longestPrefixSuffix(string s){
 
    int n = s.length();
 
    if (n == 0){
        return 0;
    }
 
    int end_suffix = n-1;
    int end_prefix = n/2 - 1;
 
    while (end_prefix >= 0){
        if (s[end_prefix] != s[end_suffix]){
            if (end_suffix != n-1){
                end_suffix = n-1;
            }
            else{
                end_prefix -= 1;
            }
        }
        else{
            end_suffix -= 1;
            end_prefix -= 1;
        }
    }
 
    return n-end_suffix-1;
}
 
int main(){
    string s = "ABCABCABCABCABC";
    cout<<longestPrefixSuffix(s)<<endl;
 
    return 0;
}

Python3




# Python3 program to find length
# of the longest prefix which
# is also suffix
 
# Returns length of the longest prefix
# which is also suffix and the two do
# not overlap.
def longestPrefixSuffix(s):
 
    n = len(s)
 
    if n == 0:
        return 0
 
    # end_suffix and end_prefix are used to keep track of the common suffix and prefix respectively.
    # For the prefix we search only in first half of string (0-->n//2-1) since
    # suffix and prefix do not overlap.
    end_suffix = n-1
    end_prefix = n // 2 - 1
 
    # Traverse each character of suffix from end to start and check for a match of prefix
    # in first half of array.
    while end_prefix >= 0:
        if s[end_prefix] != s[end_suffix]:
            if end_suffix != n-1:
                end_suffix = n-1  # reset end_suffix
            else:
                end_prefix -= 1
        else:
            end_suffix -= 1
            end_prefix -= 1
 
    # The longest common suffix and prefix is s[end+1:]
    return n-end_suffix-1
 
 
# Driver Code
if __name__ == "__main__":
    s = "ABCABCABCABCABC"
    print(longestPrefixSuffix(s))
 
# This code is contributed by Reshma Koshy.

Javascript




// JavaScript program to find length
// of the longest prefix which
// is also suffix
 
// Returns length of the longest prefix
// which is also suffix and the two do
// not overlap.
function longestPrefixSuffix(s) {
 
    let n = s.length;
     
    if (n === 0) {
        return 0;
    }
     
    // end_suffix and end_prefix are used to keep track of the common suffix and prefix respectively.
    // For the prefix we search only in first half of string (0-->n//2-1) since
    // suffix and prefix do not overlap.
    let end_suffix = n - 1;
    let end_prefix = Math.floor(n / 2) - 1;
     
    // Traverse each character of suffix from end to start and check for a match of prefix
    // in first half of array.
    while (end_prefix >= 0) {
        if (s[end_prefix] !== s[end_suffix]) {
            if (end_suffix !== n - 1) {
                end_suffix = n - 1; // reset end_suffix
            } else {
                end_prefix -= 1;
            }
        } else {
            end_suffix -= 1;
            end_prefix -= 1;
        }
    }
 
    // The longest common suffix and prefix is s[end+1:]
    return n - end_suffix - 1;
}
 
// Driver Code
let s = "ABCABCABCABCABC";
console.log(longestPrefixSuffix(s));

Output

6

Time Complexity: O(n)
Auxiliary Space: O(1)


My Personal Notes arrow_drop_up
Like Article
Save Article
Similar Reads
Related Tutorials