先决条件: Z 算法
给定一个字符串S ,任务是找到在执行给定步骤后可以形成的最大回文数:
- 选择一个非空前缀P和一个等长的非空子串T。
- 反转P或T并将它们连接起来。
注意: P 和 T 可以重叠。
例子:
Input: S = “abab”
Output: 6
Explanation:
Consider prefix as S[0 : 1] (= “ab“) and reverse the substring S[2 : 3]. Resultant string after concatenating prefix with reversed substring is “abba”, which is a palindrome.
All possible prefixes are [“a”, “ab”, ”aba”, ”abab”].
All possible suffixes are [“a”, ”b”, ”a”, ”b”, ”ab”, ”ba”, ”ab”, ”aba”, ”bab”, ”abab”].
Therefore, all possible palindromes are [“aa”, ”aa”, ”abba”, ”abba”, ”abaaba”, ”ababbaba”].
Input: S = “abcd”
Output: 4
朴素的方法:生成所有可能的前缀和所有可能的子字符串。连接所有等长前缀和子串(反转后)对,并检查获得的字符串是否为回文。
时间复杂度: O(N 3 )
辅助空间: O(N 2 )
高效的方法:可以根据观察到的连接字符串的长度总是偶数来优化上述方法。因此,只需要考虑前半部分是后半部分镜像的那些字符串。因此,问题简化为为每个可能的前缀计算与该前缀相等的子串,这可以使用 Z-function 来完成。
The z-function over a string will return an array Z[] where Z[i] represents the length of the longest prefix that same as the sub-string starting at position i and ending at position i+Z[i]. Hence, the count will be .
请按照以下步骤解决问题:
- 这个想法是维护一个区间[l, r] ,它是具有最大r的区间,使得[l, r]是一个前缀子串(子串也是前缀)。
- 如果i ≤ r ,则Z[i]等于r – i + 1和Z[i – 1] 的最小值。
- 现在,增量Z [I],直到我+ Z [i]是小于N和字符在指数Z [i]和I + Z [I]是给定字符串中相等。
- 现在,如果i + Z[i] – 1 > r ,则将l设置为i ,将r 设置为i + Z[i] – 1 。
- 对i从0到N-1重复上述步骤。
- 答案是每个i (0 ≤ i ≤ N-1)的Z[i] + 1的总和。
下面是上述方法的实现:
C++14
// C++ program the above approach
#include
using namespace std;
// Function to calculate the
// number of palindromes
int countPalindromes(string S)
{
int N = (int)S.length();
vector Z(N);
// Calculation of Z-array
int l = 0, r = 0;
for (int i = 1; i < N; i++) {
if (i <= r)
Z[i] = min(r - i + 1, Z[i - l]);
while (i + Z[i] < N
&& S[Z[i]] == S[i + Z[i]]) {
Z[i]++;
}
if (i + Z[i] - 1 > r) {
l = i;
r = i + Z[i] - 1;
}
}
// Calculation of sigma(Z[i]+1)
int sum = 0;
for (int i = 0; i < Z.size(); i++) {
sum += Z[i] + 1;
}
// Return the count
return sum;
}
// Driver Code
int main()
{
// Given String
string S = "abab";
cout << countPalindromes(S);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to calculate the
// number of palindromes
static int countPalindromes(String S)
{
int N = (int)S.length();
int[] Z = new int[(N)];
// Calculation of Z-array
int l = 0, r = 0;
for(int i = 1; i < N; i++)
{
if (i <= r)
Z[i] = Math.min(r - i + 1,
Z[i - l]);
while (i + Z[i] < N &&
S.charAt(Z[i]) ==
S.charAt(i + Z[i]))
{
Z[i]++;
}
if (i + Z[i] - 1 > r)
{
l = i;
r = i + Z[i] - 1;
}
}
// Calculation of sigma(Z[i]+1)
int sum = 0;
for(int i = 0; i < Z.length; i++)
{
sum += Z[i] + 1;
}
// Return the count
return sum;
}
// Driver Code
public static void main (String[] args)
{
// Given String
String S = "abab";
System.out.println(countPalindromes(S));
}
}
// This code is contributed by code_hunt
Python3
# Python3 program the above approach
# Function to calculate the
# number of palindromes
def countPalindrome(S):
N = len(S)
Z = [0] * N
# Calculation of Z-array
l = 0
r = 0
for i in range(1, N):
if i <= r:
Z[i] = min(r - i + 1, Z[i - 1])
while((i + Z[i]) < N and (S[Z[i]] == S[i + Z[i]])):
Z[i] += 1
if ((i + Z[i] - 1) > r):
l = ir = i + Z[i] - 1
# Calculation of sigma(Z[i]+1)
sum = 0
for i in range(0, len(Z)):
sum += Z[i] + 1
# return the count
return sum
# Driver code
# Given String
S = "abab"
print(countPalindrome(S))
# This code is contributed by virusbuddah
C#
// C# program for the above approach
using System;
public class GFG{
// Function to calculate the
// number of palindromes
static int countPalindromes(String S)
{
int N = (int)S.Length;
int[] Z = new int[(N)];
// Calculation of Z-array
int l = 0, r = 0;
for(int i = 1; i < N; i++)
{
if (i <= r)
Z[i] = Math.Min(r - i + 1,
Z[i - l]);
while (i + Z[i] < N &&
S[Z[i]] ==
S[i + Z[i]])
{
Z[i]++;
}
if (i + Z[i] - 1 > r)
{
l = i;
r = i + Z[i] - 1;
}
}
// Calculation of sigma(Z[i]+1)
int sum = 0;
for(int i = 0; i < Z.Length; i++)
{
sum += Z[i] + 1;
}
// Return the count
return sum;
}
// Driver Code
public static void Main(String[] args)
{
// Given String
String S = "abab";
Console.WriteLine(countPalindromes(S));
}
}
// This code is contributed by 29AjayKumar
Javascript
6
时间复杂度: O(N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live