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 : S = aabcdaabc
Output : 4
Explanation: The string “aabc” is the longest prefix which is also suffix.
Input : S = abcab
Output : 2
Input : S = aaaa
Output : 2
Naive approach:
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++
#include <bits/stdc++.h>
using namespace std;
int largest_prefix_suffix( const std::string
&str)
{
int n = str.length();
if (n < 2) {
return 0;
}
int len = 0;
int i = 1;
while (i < n)
{
if (str[i] == str[len])
{
++len;
++i;
}
else
{
i = i - len + 1;
len = 0;
}
}
return len>n/2? len/2:len;
}
int main()
{
string s = "blablabla" ;
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 < 2) {
return 0;
}
int len = 0;
int i = 1;
while (i < n) {
if (str[i] == str[len]) {
++len;
++i;
}
else {
i = i - len + 1;
len = 0;
}
}
return len > n / 2 ? len / 2 : len;
}
int main()
{
const char * s = "blablabla" ;
printf ( "%d\n" , largest_prefix_suffix(s));
return 0;
}
|
Java
class GFG
{
static int longestPrefixSuffix(String s)
{
int n = s.length();
if (n < 2 ) {
return 0 ;
}
int len = 0 ;
int i = (n + 1 )/ 2 ;
while (i < n)
{
if (s.charAt(i) == s.charAt(len))
{
++len;
++i;
}
else
{
i = i - len + 1 ;
len = 0 ;
}
}
return len;
}
public static void main (String[] args)
{
String s = "abcaabc" ;
System.out.println(longestPrefixSuffix(s));
}
}
|
Python3
def longestPrefixSuffix(s) :
n = len (s)
for res in range (n / / 2 , 0 , - 1 ) :
prefix = s[ 0 : res]
suffix = s[n - res: n]
if (prefix = = suffix) :
return res
return 0
if __name__ = = "__main__" :
s = "blablabla"
print (longestPrefixSuffix(s))
|
C#
using System;
class GFG
{
static int longestPrefixSuffix(String s)
{
int n = s.Length;
if (n < 2) {
return 0;
}
int len = 0;
int i = (n + 1)/2;
while (i < n)
{
if (str[i] == str[len])
{
++len;
++i;
}
else
{
i = i - len + 1;
len = 0;
}
}
return len;
}
public static void Main ()
{
String s = "blablabla" ;
Console.WriteLine(longestPrefixSuffix(s));
}
}
|
Javascript
<script>
function longestPrefixSuffix(s)
{
var n = s.length;
if (n < 2) {
return 0;
}
var len = 0;
var i = (n + 1)/2;
while (i < n)
{
if (s[i] == s[len])
{
++len;
++i;
}
else
{
i = i - len + 1;
len = 0;
}
}
return len;
}
var s = "blablabla" ;
document.write(longestPrefixSuffix(s));
</script>
|
Time Complexity: O(n^2)
Auxiliary Space: O(1)
Longest prefix which is also suffix using KMP algorithm:
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<bits/stdc++.h>
using namespace std;
int longestPrefixSuffix(string s)
{
int n = s.length();
int lps[n];
lps[0] = 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()
{
string s = "bbabbabb" ;
cout << longestPrefixSuffix(s);
return 0;
}
|
C
#include <stdio.h>
#include <string.h>
int longestPrefixSuffix( const char * s)
{
int n = strlen (s);
int lps[n];
lps[0] = 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;
}
|
Java
class GFG
{
static int longestPrefixSuffix(String s)
{
int n = s.length();
int lps[] = new int [n];
lps[ 0 ] = 0 ;
int len = 0 ;
int i = (n+ 1 )/ 2 ;
while (i < n)
{
if (s.charAt(i) == s.charAt(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;
}
public static void main (String[] args)
{
String s = "bbabbabb" ;
System.out.println(longestPrefixSuffix(s));
}
}
|
Python3
def longestPrefixSuffix(s) :
n = len (s)
lps = [ 0 ] * n
l = 0
i = (n + 1 ) / / 2 ;
while (i < n) :
if (s[i] = = s[l]) :
l = l + 1
lps[i] = l
i = i + 1
else :
if (l ! = 0 ) :
l = lps[l - 1 ]
else :
lps[i] = 0
i = i + 1
res = lps[n - 1 ]
return res;
s = "bbabbabb"
print (longestPrefixSuffix(s))
|
C#
using System;
class GFG {
static int longestPrefixSuffix( string s)
{
int n = s.Length;
int []lps = new int [n];
lps[0] = 0;
int len = 0;
int i = 1;
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 > n/2) ? n/2 : res;
}
public static void Main ()
{
string s = "abcab" ;
Console.WriteLine(longestPrefixSuffix(s));
}
}
|
Javascript
<script>
function longestPrefixSuffix(s)
{
var n = s.length;
var lps = Array.from({length: n}, (_, i) => 0);
lps[0] = 0;
var len = 0;
var i = 1;
while (i < n)
{
if (s.charAt(i) == s.charAt(len))
{
len++;
lps[i] = len;
i++;
}
else
{
if (len != 0)
{
len = lps[len-1];
}
else
{
lps[i] = 0;
i++;
}
}
}
var res = lps[n-1];
return (res > n/2)? n/2 : res;
}
var s = "abcab" ;
document.write(longestPrefixSuffix(s));
</script>
|
PHP
<?php
function longestPrefixSuffix( $s )
{
$n = strlen ( $s );
$lps [ $n ] = NULL;
$lps [0] = 0;
$len = 0;
$i = 1;
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 ++;
}
}
}
$res = $lps [ $n -1];
return ( $res > $n /2)? $n /2 : $res ;
}
$s = "abcab" ;
echo longestPrefixSuffix( $s );
?>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
Please refer computeLPSArray() of KMP search for an explanation.