给定长度为N的字符串S ,任务是从给定的字符串找到最长回文子字符串的长度。
例子:
Input: S = “abcbab”
Output: 5
Explanation:
string “abcba” is the longest substring that is a palindrome which is of length 5.
Input: S = “abcdaa”
Output: 2
Explanation:
string “aa” is the longest substring that is a palindrome which is of length 2.
天真的方法:解决问题的最简单方法是生成给定字符串的所有可能的子字符串,并打印最长的子字符串的长度,即回文。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to obtain the length of
// the longest palindromic substring
int longestPalSubstr(string str)
{
// Length of given string
int n = str.size();
// Stores the maximum length
int maxLength = 1, start = 0;
// Iterate over the string
for (int i = 0;
i < str.length(); i++) {
// Iterate over the string
for (int j = i;
j < str.length(); j++) {
int flag = 1;
// Check for palindrome
for (int k = 0;
k < (j - i + 1) / 2; k++)
if (str[i + k]
!= str[j - k])
flag = 0;
// If string [i, j - i + 1]
// is palindromic
if (flag
&& (j - i + 1) > maxLength) {
start = i;
maxLength = j - i + 1;
}
}
}
// Return length of LPS
return maxLength;
}
// Driver Code
int main()
{
// Given string
string str = "forgeeksskeegfor";
// Function Call
cout << longestPalSubstr(str);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
class GFG{
// Function to obtain the length of
// the longest palindromic substring
static int longestPalSubstr(String str)
{
// Length of given string
int n = str.length();
// Stores the maximum length
int maxLength = 1, start = 0;
// Iterate over the string
for(int i = 0; i < str.length(); i++)
{
// Iterate over the string
for(int j = i; j < str.length(); j++)
{
int flag = 1;
// Check for palindrome
for(int k = 0;
k < (j - i + 1) / 2; k++)
if (str.charAt(i + k) !=
str.charAt(j - k))
flag = 0;
// If string [i, j - i + 1]
// is palindromic
if (flag != 0 &&
(j - i + 1) > maxLength)
{
start = i;
maxLength = j - i + 1;
}
}
}
// Return length of LPS
return maxLength;
}
// Driver Code
public static void main (String[] args)
{
// Given string
String str = "forgeeksskeegfor";
// Function call
System.out.print(longestPalSubstr(str));
}
}
// This code is contributed by code_hunt
Python3
# Python3 program for the above approach
# Function to obtain the length of
# the longest palindromic substring
def longestPalSubstr(str):
# Length of given string
n = len(str)
# Stores the maximum length
maxLength = 1
start = 0
# Iterate over the string
for i in range(len(str)):
# Iterate over the string
for j in range(i, len(str), 1):
flag = 1
# Check for palindrome
for k in range((j - i + 1) // 2):
if (str[i + k] != str[j - k]):
flag = 0
# If string [i, j - i + 1]
# is palindromic
if (flag != 0 and
(j - i + 1) > maxLength):
start = i
maxLength = j - i + 1
# Return length of LPS
return maxLength
# Driver Code
# Given string
str = "forgeeksskeegfor"
# Function call
print(longestPalSubstr(str))
# This code is contributed by code_hunt
C#
// C# program for the above approach
using System;
class GFG{
// Function to obtain the length of
// the longest palindromic substring
static int longestPalSubstr(string str)
{
// Length of given string
int n = str.Length;
// Stores the maximum length
int maxLength = 1, start = 0;
// Iterate over the string
for(int i = 0; i < str.Length; i++)
{
// Iterate over the string
for(int j = i; j < str.Length; j++)
{
int flag = 1;
// Check for palindrome
for(int k = 0;
k < (j - i + 1) / 2; k++)
if (str[i + k] != str[j - k])
flag = 0;
// If string [i, j - i + 1]
// is palindromic
if (flag != 0 &&
(j - i + 1) > maxLength)
{
start = i;
maxLength = j - i + 1;
}
}
}
// Return length of LPS
return maxLength;
}
// Driver Code
public static void Main ()
{
// Given string
string str = "forgeeksskeegfor";
// Function call
Console.Write(longestPalSubstr(str));
}
}
// This code is contributed by code_hunt
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the length of
// the longest palindromic substring
int longestPalSubstr(string str)
{
// Length of string str
int n = str.size();
// Stores the dp states
bool table[n][n];
// Initialise table[][] as false
memset(table, 0, sizeof(table));
// All substrings of length 1
// are palindromes
int maxLength = 1;
for (int i = 0; i < n; ++i)
table[i][i] = true;
// Check for sub-string of length 2
int start = 0;
for (int i = 0; i < n - 1; ++i) {
// If adjacent character are same
if (str[i] == str[i + 1]) {
// Update table[i][i + 1]
table[i][i + 1] = true;
start = i;
maxLength = 2;
}
}
// Check for lengths greater than 2
// k is length of substring
for (int k = 3; k <= n; ++k) {
// Fix the starting index
for (int i = 0; i < n - k + 1; ++i) {
// Ending index of substring
// of length k
int j = i + k - 1;
// Check for palindromic
// substring str[i, j]
if (table[i + 1][j - 1]
&& str[i] == str[j]) {
// Mark true
table[i][j] = true;
// Update the maximum length
if (k > maxLength) {
start = i;
maxLength = k;
}
}
}
}
// Return length of LPS
return maxLength;
}
// Driver Code
int main()
{
// Given string str
string str = "forgeeksskeegfor";
// Function Call
cout << longestPalSubstr(str);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find the length of
// the longest palindromic subString
static int longestPalSubstr(String str)
{
// Length of String str
int n = str.length();
// Stores the dp states
boolean [][]table = new boolean[n][n];
// All subStrings of length 1
// are palindromes
int maxLength = 1;
for(int i = 0; i < n; ++i)
table[i][i] = true;
// Check for sub-String of length 2
int start = 0;
for(int i = 0; i < n - 1; ++i)
{
// If adjacent character are same
if (str.charAt(i) == str.charAt(i + 1))
{
// Update table[i][i + 1]
table[i][i + 1] = true;
start = i;
maxLength = 2;
}
}
// Check for lengths greater than 2
// k is length of subString
for(int k = 3; k <= n; ++k)
{
// Fix the starting index
for(int i = 0; i < n - k + 1; ++i)
{
// Ending index of subString
// of length k
int j = i + k - 1;
// Check for palindromic
// subString str[i, j]
if (table[i + 1][j - 1] &&
str.charAt(i) == str.charAt(j))
{
// Mark true
table[i][j] = true;
// Update the maximum length
if (k > maxLength)
{
start = i;
maxLength = k;
}
}
}
}
// Return length of LPS
return maxLength;
}
// Driver Code
public static void main(String[] args)
{
// Given String str
String str = "forgeeksskeegfor";
// Function Call
System.out.print(longestPalSubstr(str));
}
}
// This code is contributed by Amit Katiyar
C#
// C# program for
// the above approach
using System;
class GFG{
// Function to find the length of
// the longest palindromic subString
static int longestPalSubstr(String str)
{
// Length of String str
int n = str.Length;
// Stores the dp states
bool [,]table = new bool[n, n];
// All subStrings of length 1
// are palindromes
int maxLength = 1;
for(int i = 0; i < n; ++i)
table[i, i] = true;
// Check for sub-String
// of length 2
int start = 0;
for(int i = 0; i < n - 1; ++i)
{
// If adjacent character are same
if (str[i] == str[i + 1])
{
// Update table[i,i + 1]
table[i, i + 1] = true;
start = i;
maxLength = 2;
}
}
// Check for lengths greater than 2
// k is length of subString
for(int k = 3; k <= n; ++k)
{
// Fix the starting index
for(int i = 0; i < n - k + 1; ++i)
{
// Ending index of subString
// of length k
int j = i + k - 1;
// Check for palindromic
// subString str[i, j]
if (table[i + 1, j - 1] &&
str[i] == str[j])
{
// Mark true
table[i, j] = true;
// Update the maximum length
if (k > maxLength)
{
start = i;
maxLength = k;
}
}
}
}
// Return length of LPS
return maxLength;
}
// Driver Code
public static void Main(String[] args)
{
// Given String str
String str = "forgeeksskeegfor";
// Function Call
Console.Write(longestPalSubstr(str));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python program for the above approach
# Function to find the length of
# the longest palindromic subString
def longestPalSubstr(str):
# Length of String str
n = len(str);
# Stores the dp states
table = [[False for i in range(n)] for j in range(n)];
# All subStrings of length 1
# are palindromes
maxLength = 1;
for i in range(n):
table[i][i] = True;
# Check for sub-String of length 2
start = 0;
for i in range(n - 1):
# If adjacent character are same
if (str[i] == str[i + 1]):
# Update table[i][i + 1]
table[i][i + 1] = True;
start = i;
maxLength = 2;
# Check for lengths greater than 2
# k is length of subString
for k in range(3, n + 1):
# Fix the starting index
for i in range(n - k + 1):
# Ending index of subString
# of length k
j = i + k - 1;
# Check for palindromic
# subString str[i, j]
if (table[i + 1][j - 1] and str[i] == str[j]):
# Mark True
table[i][j] = True;
# Update the maximum length
if (k > maxLength):
start = i;
maxLength = k;
# Return length of LPS
return maxLength;
# Driver Code
if __name__ == '__main__':
# Given String str
str = "forgeeksskeegfor";
# Function Call
print(longestPalSubstr(str));
# This code is contributed by 29AjayKumar
Python3
# Python program for the above approach
# Function that placed '#' intermediately
# before and after each character
def UpdatedString(string):
newString = ['#']
# Traverse the string
for char in string:
newString += [char, '#']
# Return the string
return ''.join(newString)
# Function that finds the length of
# the longest palindromic substring
def Manacher(string):
# Update the string
string = UpdatedString(string)
# Stores the longest proper prefix
# which is also a suffix
LPS = [0 for _ in range(len(string))]
C = 0
R = 0
for i in range(len(string)):
imir = 2 * C - i
# Find the minimum length of
# the palindrome
if R > i:
LPS[i] = min(R-i, LPS[imir])
else:
# Find the actual length of
# the palindrome
LPS[i] = 0
# Exception Handling
try:
while string[i + 1 + LPS[i]] \
== string[i - 1 - LPS[i]]:
LPS[i] += 1
except:
pass
# Update C and R
if i + LPS[i] > R:
C = i
R = i + LPS[i]
r, c = max(LPS), LPS.index(max(LPS))
# Return the length r
return r
# Driver code
# Given string str
str = "forgeeksskeegfor"
# Function Call
print(Manacher(str))
10
时间复杂度: O(N 3 ),其中N是给定字符串的长度。
辅助空间: O(N)
动态编程方法:可以通过存储重叠子问题的结果来优化上述方法。这个想法类似于这篇文章。步骤如下:
- 保持以自下而上的方式填充的布尔表[N] [N] 。
- 如果子字符串是回文,则table [i] [j]的值为true,否则为false。
- 要计算table [i] [j] ,请检查table [i + 1] [j – 1]的值,如果该值为true且str [i]与str [j]相同,则更新table [i] [j]是的。
- 否则,将table [i] [j]的值更新为false。
下面是字符串“ geeks”的图示:
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the length of
// the longest palindromic substring
int longestPalSubstr(string str)
{
// Length of string str
int n = str.size();
// Stores the dp states
bool table[n][n];
// Initialise table[][] as false
memset(table, 0, sizeof(table));
// All substrings of length 1
// are palindromes
int maxLength = 1;
for (int i = 0; i < n; ++i)
table[i][i] = true;
// Check for sub-string of length 2
int start = 0;
for (int i = 0; i < n - 1; ++i) {
// If adjacent character are same
if (str[i] == str[i + 1]) {
// Update table[i][i + 1]
table[i][i + 1] = true;
start = i;
maxLength = 2;
}
}
// Check for lengths greater than 2
// k is length of substring
for (int k = 3; k <= n; ++k) {
// Fix the starting index
for (int i = 0; i < n - k + 1; ++i) {
// Ending index of substring
// of length k
int j = i + k - 1;
// Check for palindromic
// substring str[i, j]
if (table[i + 1][j - 1]
&& str[i] == str[j]) {
// Mark true
table[i][j] = true;
// Update the maximum length
if (k > maxLength) {
start = i;
maxLength = k;
}
}
}
}
// Return length of LPS
return maxLength;
}
// Driver Code
int main()
{
// Given string str
string str = "forgeeksskeegfor";
// Function Call
cout << longestPalSubstr(str);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find the length of
// the longest palindromic subString
static int longestPalSubstr(String str)
{
// Length of String str
int n = str.length();
// Stores the dp states
boolean [][]table = new boolean[n][n];
// All subStrings of length 1
// are palindromes
int maxLength = 1;
for(int i = 0; i < n; ++i)
table[i][i] = true;
// Check for sub-String of length 2
int start = 0;
for(int i = 0; i < n - 1; ++i)
{
// If adjacent character are same
if (str.charAt(i) == str.charAt(i + 1))
{
// Update table[i][i + 1]
table[i][i + 1] = true;
start = i;
maxLength = 2;
}
}
// Check for lengths greater than 2
// k is length of subString
for(int k = 3; k <= n; ++k)
{
// Fix the starting index
for(int i = 0; i < n - k + 1; ++i)
{
// Ending index of subString
// of length k
int j = i + k - 1;
// Check for palindromic
// subString str[i, j]
if (table[i + 1][j - 1] &&
str.charAt(i) == str.charAt(j))
{
// Mark true
table[i][j] = true;
// Update the maximum length
if (k > maxLength)
{
start = i;
maxLength = k;
}
}
}
}
// Return length of LPS
return maxLength;
}
// Driver Code
public static void main(String[] args)
{
// Given String str
String str = "forgeeksskeegfor";
// Function Call
System.out.print(longestPalSubstr(str));
}
}
// This code is contributed by Amit Katiyar
C#
// C# program for
// the above approach
using System;
class GFG{
// Function to find the length of
// the longest palindromic subString
static int longestPalSubstr(String str)
{
// Length of String str
int n = str.Length;
// Stores the dp states
bool [,]table = new bool[n, n];
// All subStrings of length 1
// are palindromes
int maxLength = 1;
for(int i = 0; i < n; ++i)
table[i, i] = true;
// Check for sub-String
// of length 2
int start = 0;
for(int i = 0; i < n - 1; ++i)
{
// If adjacent character are same
if (str[i] == str[i + 1])
{
// Update table[i,i + 1]
table[i, i + 1] = true;
start = i;
maxLength = 2;
}
}
// Check for lengths greater than 2
// k is length of subString
for(int k = 3; k <= n; ++k)
{
// Fix the starting index
for(int i = 0; i < n - k + 1; ++i)
{
// Ending index of subString
// of length k
int j = i + k - 1;
// Check for palindromic
// subString str[i, j]
if (table[i + 1, j - 1] &&
str[i] == str[j])
{
// Mark true
table[i, j] = true;
// Update the maximum length
if (k > maxLength)
{
start = i;
maxLength = k;
}
}
}
}
// Return length of LPS
return maxLength;
}
// Driver Code
public static void Main(String[] args)
{
// Given String str
String str = "forgeeksskeegfor";
// Function Call
Console.Write(longestPalSubstr(str));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python program for the above approach
# Function to find the length of
# the longest palindromic subString
def longestPalSubstr(str):
# Length of String str
n = len(str);
# Stores the dp states
table = [[False for i in range(n)] for j in range(n)];
# All subStrings of length 1
# are palindromes
maxLength = 1;
for i in range(n):
table[i][i] = True;
# Check for sub-String of length 2
start = 0;
for i in range(n - 1):
# If adjacent character are same
if (str[i] == str[i + 1]):
# Update table[i][i + 1]
table[i][i + 1] = True;
start = i;
maxLength = 2;
# Check for lengths greater than 2
# k is length of subString
for k in range(3, n + 1):
# Fix the starting index
for i in range(n - k + 1):
# Ending index of subString
# of length k
j = i + k - 1;
# Check for palindromic
# subString str[i, j]
if (table[i + 1][j - 1] and str[i] == str[j]):
# Mark True
table[i][j] = True;
# Update the maximum length
if (k > maxLength):
start = i;
maxLength = k;
# Return length of LPS
return maxLength;
# Driver Code
if __name__ == '__main__':
# Given String str
str = "forgeeksskeegfor";
# Function Call
print(longestPalSubstr(str));
# This code is contributed by 29AjayKumar
10
时间复杂度: O(N 2 ),其中N是给定字符串的长度。
辅助空间: O(N)
高效方法:为了优化上述方法,其思想是使用Manacher算法。通过使用该算法,对于每个字符c ,可以找到以c为中心的最长回文子字符串,其长度为奇数。但最长回文子串的长度也可以均匀,没有任何中心。因此,一些特殊字符的每个字符之间增加。
For example, if the given string is “abababc” then it will become “$#a#b#a#b#a#b#c#@”. Now, notice that in this case, for each character c, the longest palindromic substring with the center c will have an odd length.
步骤如下:
- 如上所述,在给定的字符串S中添加特殊字符,并将其长度设为N。
- 用0初始化数组d [] ,center和r ,其中d [i]存储回文的左侧部分的长度,其中S [i]是中心, r表示最右边的访问边界,center表示当前索引。字符,它是此最右边边界的中心。
- 在遍历字符串S时,对于每个索引i ,如果i小于r,则先前已计算出其答案,并且可以将d [i]设置为等于以i为中心的字符镜像的答案,可以将其计算为(2 *中心– i) 。
- 现在,检查r后面是否有某些字符,以使回文变得越来越长。
- 如果(i + d [i])大于r ,则更新r = (i + d [i])并以i为中心。
- 在找到以每个字符c为中心的最长回文之后,打印(2 * d [i] + 1)/ 2的最大值,其中0≤i
因为d [i]仅存储回文的左侧部分。
下面是上述方法的实现:
Python3
# Python program for the above approach
# Function that placed '#' intermediately
# before and after each character
def UpdatedString(string):
newString = ['#']
# Traverse the string
for char in string:
newString += [char, '#']
# Return the string
return ''.join(newString)
# Function that finds the length of
# the longest palindromic substring
def Manacher(string):
# Update the string
string = UpdatedString(string)
# Stores the longest proper prefix
# which is also a suffix
LPS = [0 for _ in range(len(string))]
C = 0
R = 0
for i in range(len(string)):
imir = 2 * C - i
# Find the minimum length of
# the palindrome
if R > i:
LPS[i] = min(R-i, LPS[imir])
else:
# Find the actual length of
# the palindrome
LPS[i] = 0
# Exception Handling
try:
while string[i + 1 + LPS[i]] \
== string[i - 1 - LPS[i]]:
LPS[i] += 1
except:
pass
# Update C and R
if i + LPS[i] > R:
C = i
R = i + LPS[i]
r, c = max(LPS), LPS.index(max(LPS))
# Return the length r
return r
# Driver code
# Given string str
str = "forgeeksskeegfor"
# Function Call
print(Manacher(str))
10
时间复杂度: O(N),其中N是给定字符串的长度。
辅助空间: O(N)