删除具有重复子字符串的字符串的最长前缀
给定一个长度为N的字符串S ,任务是删除在S中存在至少一个重复子字符串的字符串的最长前缀。
注意:重复的子字符串不能是前缀本身
例子:
Input: S = “GeeksforGeeks”
Output: “forGeeks”
Explanation: The longest substring which has a duplicate is “Geeks”.
After deleting this the remaining string becomes “forGeeks”.
Input: S = “aaaaa”
Output: “a”
Explanation: Here the longest prefix which has a duplicate substring is “aaaa”.
So after deleting this the remaining string is “a”.
Note that the whole string is not selected because then the duplicate string is the prefix itself.
方法:可以根据以下思路解决问题:
Find all the characters which can be a starting point of a substring which is a duplicate of the prefix. Then from these points find the duplicate of the longest prefix and delete that prefix.
请按照下图更好地理解
插图:
For example take S = “aaaaa”
The possible starting points can be at indices 1, 2, 3, 4.
For index 1: The possible duplicate of the prefix is “aaaa”.
It has length = 4
For index 2: The possible duplicate of the prefix is “aaa”.
It has length = 3
For index 3: The possible duplicate of the prefix is “aa”.
It has length = 2
For index 4: The possible duplicate of the prefix is “a”.
It has length = 1
So remove the prefix of length 4. Therefore the string becomes “a”
按照下面提到的方法解决问题:
- 使用两个指针:一个指向前缀的开头(例如i最初为0 ),另一个(例如j )查找所有可能重复子字符串的起点。
- 将 j 从 1 迭代到 N:
- 如果 S[j] 与 S[i] 匹配,则使用指针(例如 k)并迭代 i 和 k 以找到从j开始的子字符串的长度,它是前缀的副本。
- 更新最大长度。
- 再次将i设置为 0。
- 删除最大长度前缀。
下面是上述方法的实现:
C++
// C++ code for the above approach:
#include
using namespace std;
// Function to delete the longest prefix
string delPrefix(string S)
{
if (S.size() == 1)
return S;
int i = 0, maxi = 0;
// Loop to find the
// longest duplicate of prefix
for (int j = 1; j < S.size(); j++) {
int k = j;
while (k < S.size() and S[k] == S[i]) {
k++;
i++;
}
maxi = max(maxi, i);
i = 0;
}
return S.substr(maxi);
}
// Driver code
int main()
{
string S = "aaaaa";
string ans = delPrefix(S);
// Function call
cout << ans;
return 0;
}
Java
// Java code for the above approach
import java.io.*;
class GFG
{
// Function to delete the longest prefix
public static String delPrefix(String S)
{
if (S.length() == 1)
return S;
int i = 0, maxi = 0;
// Loop to find the
// longest duplicate of prefix
for (int j = 1; j < S.length(); j++) {
int k = j;
while (k < S.length()
&& S.charAt(k) == S.charAt(i)) {
k++;
i++;
}
maxi = Math.max(maxi, i);
i = 0;
}
return S.substring(maxi);
}
public static void main(String[] args)
{
String S = "aaaaa";
String ans = delPrefix(S);
// Function call
System.out.print(ans);
}
}
// This code is contributed by Rohit Pradhan
C#
// C# code for the above approach
using System;
public class GFG{
// Function to delete the longest prefix
public static string delPrefix(string S)
{
if (S.Length == 1)
return S;
int i = 0, maxi = 0;
// Loop to find the
// longest duplicate of prefix
for (int j = 1; j < S.Length; j++) {
int k = j;
while (k < S.Length
&& S[k] == S[i]) {
k++;
i++;
}
maxi = Math.Max(maxi, i);
i = 0;
}
return S.Substring(maxi);
}
static public void Main (){
string S = "aaaaa";
string ans = delPrefix(S);
// Function call
Console.Write(ans);
}
}
// This code is contributed by hrithikgarg03188.
a
时间复杂度: O(N 2 )
辅助空间: O(1)