You are given two strings str1 and str2 of the same length. In a single shift, you can rotate one string (str2) by 1 element such that its 1st element becomes the last and the second one becomes the first like “abcd” will change to “bcda” after the one-shift operation. You have to find the minimum shift operation required to get the common prefix of maximum length from str1 and str2.
Examples:
Input : str1[] = "geeks",
str2 = "dgeek"
Output : Shift = 1,
Prefix = geek
Input : str1[] = "practicegeeks",
str2 = "coderpractice"
Output : Shift = 5
Prefix = practice
Naive Approach: Shift second string one by one and keep track of the length of the longest prefix for each shift, there is a total of n shifts and for each shift finding the length of the common prefix will take O(n) time. Hence, the overall time complexity for this approach is O(n^2).
Better Approach: If we will add a second string at the end of itself that is str2 = str2 + str2 then there is no need of finding a prefix for each shift separately. Now, after adding str2 to itself we have to only find the longest prefix of str1 present in str2 and the starting position of that prefix in str2 will give us the actual number of shifts required. For finding the longest prefix we can use KMP pattern search algorithm.
So, in this way, our time-complexity will reduce to O(n) only.
Implementation
C++
#include <bits/stdc++.h>
using namespace std;
void KMP( int m, int n, string str2, string str1)
{
int pos = 0, len = 0;
int p[m + 1];
int k = 0;
p[1] = 0;
for ( int i = 2; i <= n; i++) {
while (k > 0 && str1[k] != str1[i - 1])
k = p[k];
if (str1[k] == str1[i - 1])
++k;
p[i] = k;
}
for ( int j = 0, i = 0; i < m; i++) {
while (j > 0 && str1[j] != str2[i])
j = p[j];
if (str1[j] == str2[i])
j++;
if (j > len) {
len = j;
pos = i - j + 1;
}
}
cout << "Shift = " << pos << endl;
cout << "Prefix = " << str1.substr(0, len);
}
int main()
{
string str1 = "geeksforgeeks" ;
string str2 = "forgeeksgeeks" ;
int n = str1.size();
str2 = str2 + str2;
KMP(2 * n, n, str2, str1);
return 0;
}
|
Java
class GFG {
static void KMP( int m, int n,
String str2, String str1)
{
int pos = 0 , len = 0 ;
int []p = new int [m + 1 ];
int k = 0 ;
char []ch1 = str1.toCharArray();
char []ch2 = str2.toCharArray();
for ( int i = 2 ; i <= n; i++)
{
while (k > 0 && ch1[k] != ch1[i - 1 ])
k = p[k];
if (ch1[k] == ch1[i - 1 ])
++k;
p[i] = k;
}
for ( int j = 0 , i = 0 ; i < m; i++)
{
while (j > 0 && j < n && ch1[j] != ch2[i])
j = p[j];
if (j < n && ch1[j] == ch2[i])
j++;
if (j > len)
{
len = j;
pos = i - j + 1 ;
}
}
System.out.println( "Shift = " + pos);
System.out.println( "Prefix = " +
str1.substring( 0 ,len));
}
public static void main(String[] args)
{
String str1 = "geeksforgeeks" ;
String str2 = "forgeeksgeeks" ;
int n = str1.length();
str2 = str2 + str2;
KMP( 2 * n, n, str2, str1);
}
}
|
Python3
def KMP(m, n, str2, str1):
pos = 0
Len = 0
p = [ 0 for i in range (m + 1 )]
k = 0
for i in range ( 2 , n + 1 ):
while (k > 0 and str1[k] ! = str1[i - 1 ]):
k = p[k]
if (str1[k] = = str1[i - 1 ]):
k + = 1
p[i] = k
j = 0
for i in range (m):
while (j > 0 and j < n and str1[j] ! = str2[i]):
j = p[j]
if (j < n and str1[j] = = str2[i]):
j + = 1
if (j > Len ):
Len = j
pos = i - j + 1
print ( "Shift = " , pos)
print ( "Prefix = " , str1[: Len ])
str1 = "geeksforgeeks"
str2 = "forgeeksgeeks"
n = len (str1)
str2 = str2 + str2
KMP( 2 * n, n, str2, str1)
|
C#
using System;
class GFG {
static void KMP( int m, int n,
String str2, String str1)
{
int pos = 0, len = 0;
int []p = new int [m + 1];
int k = 0;
char []ch1 = str1.ToCharArray();
char []ch2 = str2.ToCharArray();
for ( int i = 2; i <= n; i++)
{
while (k > 0 && ch1[k] != ch1[i - 1])
k = p[k];
if (ch1[k] == ch1[i - 1])
++k;
p[i] = k;
}
for ( int j = 0, i = 0; i < m; i++)
{
while (j > 0 && j < n && ch1[j] != ch2[i])
j = p[j];
if (j < n && ch1[j] == ch2[i])
j++;
if (j > len)
{
len = j;
pos = i - j + 1;
}
}
Console.WriteLine( "Shift = " + pos);
Console.WriteLine( "Prefix = " +
str1.Substring(0,len));
}
public static void Main(String[] args)
{
String str1 = "geeksforgeeks" ;
String str2 = "forgeeksgeeks" ;
int n = str1.Length;
str2 = str2 + str2;
KMP(2 * n, n, str2, str1);
}
}
|
Javascript
<script>
function KMP(m, n, str2, str1)
{
var pos = 0, len = 0;
var p = Array(m+1).fill(0);
var k = 0;
p[1] = 0;
for ( var i = 2; i <= n; i++) {
while (k > 0 && str1[k] != str1[i - 1])
k = p[k];
if (str1[k] == str1[i - 1])
++k;
p[i] = k;
}
for ( var j = 0, i = 0; i < m; i++) {
while (j > 0 && str1[j] != str2[i])
j = p[j];
if (str1[j] == str2[i])
j++;
if (j > len) {
len = j;
pos = i - j + 1;
}
}
document.write( "Shift = " + pos + "<br>" );
document.write( "Prefix = " + str1.substr(0, len));
}
var str1 = "geeksforgeeks" ;
var str2 = "forgeeksgeeks" ;
var n = str1.length;
str2 = str2 + str2;
KMP(2 * n, n, str2, str1);
</script>
|
Output:
Shift = 8
Prefix = geeksforgeeks
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
25 Jul, 2022
Like Article
Save Article