📌  相关文章
📜  通过连接等长前缀和子串可以获得的回文数

📅  最后修改于: 2021-09-06 06:38:25             🧑  作者: Mango

先决条件: Z 算法

给定一个字符串S ,任务是找到在执行给定步骤后可以形成的最大回文数:

  1. 选择一个非空前缀P和一个等长的非空子串T。
  2. 反转PT并将它们连接起来。

注意: P 和 T 可以重叠。

例子:

朴素的方法:生成所有可能的前缀和所有可能的子字符串。连接所有等长前缀和子串(反转后)对,并检查获得的字符串是否为回文。

时间复杂度: O(N 3 )
辅助空间: O(N 2 )

高效的方法:可以根据观察到的连接字符串的长度总是偶数来优化上述方法。因此,只需要考虑前半部分是后半部分镜像的那些字符串。因此,问题简化为为每个可能的前缀计算与该前缀相等的子串,这可以使用 Z-function 来完成。

请按照以下步骤解决问题:

  1. 这个想法是维护一个区间[l, r] ,它是具有最大r的区间,使得[l, r]是一个前缀子串(子串也是前缀)。
  2. 如果i ≤ r ,则Z[i]等于r – i + 1Z[i – 1] 的最小值
  3. 现在,增量Z [I],直到我+ Z [i]是小于N和字符在指数Z [i]I + Z [I]是给定字符串中相等。
  4. 现在,如果i + Z[i] – 1 > r ,则将l设置为i ,将r 设置i + Z[i] – 1
  5. i0N-1重复上述步骤。
  6. 答案是每个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