您将获得两个长度相同的字符串str1和str2。在单个移位中,您可以将一个字符串(str2)旋转1个元素,以使其第一个元素变为最后一个元素,第二个元素变为第一个元素,例如在进行一次移位操作后,“ abcd”将变为“ bcda”。您必须找到从str1和str2获得最大长度的公共前缀所需的最小移位操作。
例子:
Input : str1[] = "geeks",
str2 = "dgeek"
Output : Shift = 1,
Prefix = geek
Input : str1[] = "practicegeeks",
str2 = "coderpractice"
Output : Shift = 5
Prefix = practice
天真的方法:逐个移位第二个字符串,并跟踪每个移位的最长前缀的长度,总共有n个移位,并且对于每个移位,找到公共前缀的长度将花费O(n)时间。因此,该方法的总时间复杂度为O(n ^ 2)。
更好的方法:如果我们将在其末尾添加第二个字符串,即str2 = str2 + str2,则无需分别为每个移位查找前缀。现在,在将str2添加到自身之后,我们仅需要找到str2中存在的最长的str1前缀,并且该前缀在str2中的起始位置将为我们提供所需的实际移位数。为了找到最长的前缀,我们可以使用KMP模式搜索算法。
因此,通过这种方式,我们的时间复杂度将仅降低到O(n)。
C++
// CPP program to find longest common prefix
// after rotation of second string.
#include
using namespace std;
// function for KMP search
void KMP(int m, int n, string str2, string str1)
{
int pos = 0, len = 0;
// preprocessing of longest proper prefix
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;
}
// find out the longest prefix and position
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++;
// for new position with longer prefix in str2
// update pos and len
if (j > len) {
len = j;
pos = i - j + 1;
}
}
// print result
cout << "Shift = " << pos << endl;
cout << "Prefix = " << str1.substr(0, len);
}
// driver function
int main()
{
string str1 = "geeksforgeeks";
string str2 = "forgeeksgeeks";
int n = str1.size();
str2 = str2 + str2;
KMP(2 * n, n, str2, str1);
return 0;
}
Java
// Java program to find longest common prefix
// after rotation of second string.
class GFG {
// function for KMP search
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;
//p[1] = 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;
}
// find out the longest prefix and position
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++;
// for new position with longer prefix in str2
// update pos and len
if (j > len)
{
len = j;
pos = i - j + 1;
}
}
// print result
System.out.println("Shift = " + pos);
System.out.println("Prefix = " +
str1.substring(0,len));
}
// Driver code
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);
}
}
// This code is contributed by Ita_c.
Python3
# Python3 program to find longest common prefix
# after rotation of second string.
# function for KMP search
def KMP(m, n, str2, str1):
pos = 0
Len = 0
# preprocessing of longest proper prefix
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
# find out the longest prefix and position
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
# for new position with longer prefix
# in str2 update pos and Len
if (j > Len):
Len = j
pos = i - j + 1
# prresult
print("Shift = ", pos)
print("Prefix = ", str1[:Len])
# Driver Code
str1 = "geeksforgeeks"
str2 = "forgeeksgeeks"
n = len(str1)
str2 = str2 + str2
KMP(2 * n, n, str2, str1)
# This code is contributed by Mohit kumar 29
C#
// C# program to find longest common prefix
// after rotation of second string.
using System;
class GFG {
// function for KMP search
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;
//p[1] = 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;
}
// find out the longest prefix and position
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++;
// for new position with longer prefix in str2
// update pos and len
if (j > len)
{
len = j;
pos = i - j + 1;
}
}
// print result
Console.WriteLine("Shift = " + pos);
Console.WriteLine("Prefix = " +
str1.Substring(0,len));
}
// Driver code
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);
}
}
/* This code contributed by PrinciRaj1992 */
输出:
Shift = 8
Prefix = geeksforgeeks