给定一个长度为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] 的值为真,否则为假。
- 要计算table[i][j] ,请检查table[i + 1][j – 1]的值,如果该值为真且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
蟒蛇3
# 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*center – i) 。
- 现在,检查 r 之后是否有一些字符使回文变得更长。
- 如果(i + d[i]) 大于 r ,则更新 r = (i + d[i])并以i为中心。
- 找到以每个字符c为中心的最长回文后,打印(2*d[i] + 1)/2的最大值,其中0 ≤ i < N,因为d[i]只存储了回文的左边部分。
下面是上述方法的实现:
蟒蛇3
# 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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live