给定字符串str ,任务是找到除去子字符串后可以从中获得的最长回文字符串。
例子:
Input: str = “abcdefghiedcba”
Output: “abcdeiedcba”
Explanation: Removal of substring “fgh” leaves the remaining string palindromic
Input: str = “abba”
Output: “abba”
Explanation: Removal of substring “” as the given string is already palindromic.
方法:
- 从给定字符串的彼此相反的两端找到最长的子字符串A和B对。
- 从原始字符串删除它们。
- 使用KMP从其余字符串的两端找到最长的回文子字符串,并考虑更长的子字符串。
- 将字符串A和B分别添加到该回文子字符串的开头和结尾以获取所需的输出。
下面的代码是上述方法的实现:
C++
// C++ Implementation of the
// above approach
#include
using namespace std;
// Function to find the longest palindrome
// from the start of the string using KMP match
string findPalindrome(string C)
{
string S = C;
reverse(S.begin(), S.end());
// Append S(reverse of C) to C
C = C + "&" + S;
int n = C.length();
int longestPalindrome[n];
longestPalindrome[0] = 0;
int len = 0;
int i = 1;
// Use KMP algorithm
while (i < n) {
if (C[i] == C[len]) {
len++;
longestPalindrome[i] = len;
i++;
}
else {
if (len != 0) {
len = longestPalindrome[len - 1];
}
else {
longestPalindrome[i] = 0;
i++;
}
}
}
string ans = C.substr(0, longestPalindrome[n - 1]);
return ans;
}
// Function to return longest palindromic
// string possible from the given string
// after removal of any substring
string findAns(string s)
{
// Initialize three strings A, B AND F
string A = "";
string B = "";
string F = "";
int i = 0;
int j = s.length() - 1;
int len = s.length();
// Loop to find longest substrings
// from both ends which are
// reverse of each other
while (i < j && s[i] == s[j]) {
i = i + 1;
j = j - 1;
}
if (i > 0)
{
A = s.substr(0, i);
B = s.substr(len - i, i);
}
// Proceed to third step of our approach
if (len > 2 * i)
{
// Remove the substrings A and B
string C = s.substr(i, s.length() - 2 * i);
// Find the longest palindromic
// substring from beginning of C
string D = findPalindrome(C);
// Find the longest palindromic
// substring from end of C
reverse(C.begin(), C.end());
string E = findPalindrome(C);
// Store the maximum of D and E in F
if (D.length() > E.length()) {
F = D;
}
else {
F = E;
}
}
// Find the final answer
string answer = A + F + B;
return answer;
}
// Driver Code
int main()
{
string str = "abcdefghiedcba";
cout << findAns(str) << endl;
}
Java
// Java Implementation of the
// above approach
import java.util.*;
class GFG{
// Function to find the longest palindrome
// from the start of the String using KMP match
static String findPalindrome(String C)
{
String S = C;
S = reverse(S);
// Append S(reverse of C) to C
C = C + "&" + S;
int n = C.length();
int []longestPalindrome = new int[n];
longestPalindrome[0] = 0;
int len = 0;
int i = 1;
// Use KMP algorithm
while (i < n) {
if (C.charAt(i) == C.charAt(len)) {
len++;
longestPalindrome[i] = len;
i++;
}
else {
if (len != 0) {
len = longestPalindrome[len - 1];
}
else {
longestPalindrome[i] = 0;
i++;
}
}
}
String ans = C.substring(0, longestPalindrome[n - 1]);
return ans;
}
// Function to return longest palindromic
// String possible from the given String
// after removal of any subString
static String findAns(String s)
{
// Initialize three Strings A, B AND F
String A = "";
String B = "";
String F = "";
int i = 0;
int j = s.length() - 1;
int len = s.length();
// Loop to find longest subStrings
// from both ends which are
// reverse of each other
while (i < j && s.charAt(i) == s.charAt(j)) {
i = i + 1;
j = j - 1;
}
if (i > 0)
{
A = s.substring(0, i);
B = s.substring(len - i, len);
}
// Proceed to third step of our approach
if (len > 2 * i)
{
// Remove the subStrings A and B
String C = s.substring(i, (s.length() - 2 * i) + i);
// Find the longest palindromic
// subString from beginning of C
String D = findPalindrome(C);
// Find the longest palindromic
// subString from end of C
C = reverse(C);
String E = findPalindrome(C);
// Store the maximum of D and E in F
if (D.length() > E.length()) {
F = D;
}
else {
F = E;
}
}
// Find the final answer
String answer = A + F + B;
return answer;
}
static String reverse(String input) {
char[] a = input.toCharArray();
int l, r = a.length - 1;
for (l = 0; l < r; l++, r--) {
char temp = a[l];
a[l] = a[r];
a[r] = temp;
}
return String.valueOf(a);
}
// Driver Code
public static void main(String[] args)
{
String str = "abcdefghiedcba";
System.out.print(findAns(str) +"\n");
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 implementation of the
# above approach
# Function to find the longest
# palindrome from the start of
# the string using KMP match
def findPalindrome(C):
S = C[::-1]
# Append S(reverse of C) to C
C = C[:] + '&' + S
n = len(C)
longestPalindrome = [0 for i in range(n)]
longestPalindrome[0] = 0
ll = 0
i = 1
# Use KMP algorithm
while (i < n):
if (C[i] == C[ll]):
ll += 1
longestPalindrome[i] = ll
i += 1
else:
if (ll != 0):
ll = longestPalindrome[ll - 1]
else:
longestPalindrome[i] = 0
i += 1
ans = C[0:longestPalindrome[n - 1]]
return ans
# Function to return longest palindromic
# string possible from the given string
# after removal of any substring
def findAns(s):
# Initialize three strings
# A, B AND F
A = ""
B = ""
F = ""
i = 0
j = len(s) - 1
ll = len(s)
# Loop to find longest substrings
# from both ends which are
# reverse of each other
while (i < j and s[i] == s[j]):
i = i + 1
j = j - 1
if (i > 0):
A = s[0 : i]
B = s[ll - i : ll]
# Proceed to third step of our approach
if (ll > 2 * i):
# Remove the substrings A and B
C = s[i : i + (len(s) - 2 * i)]
# Find the longest palindromic
# substring from beginning of C
D = findPalindrome(C)
# Find the longest palindromic
# substring from end of C
C = C[::-1]
E = findPalindrome(C)
# Store the maximum of D and E in F
if (len(D) > len(E)):
F = D
else:
F = E
# Find the final answer
answer = A + F + B
return answer
# Driver code
if __name__=="__main__":
str = "abcdefghiedcba"
print(findAns(str))
# This code is contributed by rutvik_56
C#
// C# Implementation of the
// above approach
using System;
class GFG{
// Function to find the longest palindrome
// from the start of the String using KMP match
static String findPalindrome(String C)
{
String S = C;
S = reverse(S);
// Append S(reverse of C) to C
C = C + "&" + S;
int n = C.Length;
int []longestPalindrome = new int[n];
longestPalindrome[0] = 0;
int len = 0;
int i = 1;
// Use KMP algorithm
while (i < n) {
if (C[i] == C[len]) {
len++;
longestPalindrome[i] = len;
i++;
}
else {
if (len != 0) {
len = longestPalindrome[len - 1];
}
else {
longestPalindrome[i] = 0;
i++;
}
}
}
String ans = C.Substring(0, longestPalindrome[n - 1]);
return ans;
}
// Function to return longest palindromic
// String possible from the given String
// after removal of any subString
static String findAns(String s)
{
// Initialize three Strings A, B AND F
String A = "";
String B = "";
String F = "";
int i = 0;
int j = s.Length - 1;
int len = s.Length;
// Loop to find longest subStrings
// from both ends which are
// reverse of each other
while (i < j && s[i] == s[j]) {
i = i + 1;
j = j - 1;
}
if (i > 0)
{
A = s.Substring(0, i);
B = s.Substring(len - i, i);
}
// Proceed to third step of our approach
if (len > 2 * i)
{
// Remove the subStrings A and B
String C = s.Substring(i, (s.Length - 2 * i));
// Find the longest palindromic
// subString from beginning of C
String D = findPalindrome(C);
// Find the longest palindromic
// subString from end of C
C = reverse(C);
String E = findPalindrome(C);
// Store the maximum of D and E in F
if (D.Length > E.Length) {
F = D;
}
else {
F = E;
}
}
// Find the readonly answer
String answer = A + F + B;
return answer;
}
static String reverse(String input) {
char[] a = input.ToCharArray();
int l, r = a.Length - 1;
for (l = 0; l < r; l++, r--) {
char temp = a[l];
a[l] = a[r];
a[r] = temp;
}
return String.Join("",a);
}
// Driver Code
public static void Main(String[] args)
{
String str = "abcdefghiedcba";
Console.Write(findAns(str) +"\n");
}
}
// This code is contributed by Rajput-Ji
输出:
abcdeiedcba
时间复杂度: O(N)