给定字符串小写ASCII字符,找到它的所有不同的连续回文子字符串。
例子:
Input: str = "abaaa"
Output: Below are 5 palindrome sub-strings
a
aa
aaa
aba
b
Input: str = "geek"
Output: Below are 4 palindrome sub-strings
e
ee
g
k
步骤1:使用改良的Manacher算法查找所有回文:
将每个字符视为枢轴,在两侧展开以找到以所考虑的枢轴字符为中心的偶数和奇数回文长度,并将其长度存储在2个数组中(奇数和偶数)。
此步骤的时间复杂度为O(n ^ 2)
步骤2:在HashMap中插入所有找到的回文:
将上一步中找到的所有回文插入到HashMap中。还将字符串的所有单个字符插入HashMap(以生成不同的单字母回文子字符串)。
假设哈希插入搜索花费O(1)时间,则此步骤的时间复杂度为O(n ^ 3)。请注意,一个字符串最多可以有O(n ^ 2)个回文子字符串。在下面的C++代码中,使用了有序哈希表,其中插入和搜索的时间复杂度为O(Logn)。在C++中,有序哈希图是使用Red Black Tree实现的。
步骤3:打印不同的回文数以及这些不同的回文数:
最后一步是打印存储在HashMap中的所有值(由于HashMap的属性,仅散列不同的元素)。图的大小给出了不同回文连续子串的数量。
以下是上述想法的实现。
C/C++
// C++ program to find all distinct palindrome sub-strings
// of a given string
#include
#include
Java
// Java program to find all distinct palindrome
// sub-strings of a given string
import java.util.Map;
import java.util.TreeMap;
public class GFG
{
// Function to print all distinct palindrome
// sub-strings of s
static void palindromeSubStrs(String s)
{
//map m;
TreeMap m = new TreeMap<>();
int n = s.length();
// table for storing results (2 rows for odd-
// and even-length palindromes
int[][] R = new int[2][n+1];
// Find all sub-string palindromes from the
// given input string insert 'guards' to
// iterate easily over s
s = "@" + s + "#";
for (int j = 0; j <= 1; j++)
{
int rp = 0; // length of 'palindrome radius'
R[j][0] = 0;
int i = 1;
while (i <= n)
{
// Attempt to expand palindrome centered
// at i
while (s.charAt(i - rp - 1) == s.charAt(i +
j + rp))
rp++; // Incrementing the length of
// palindromic radius as and
// when we find vaid palindrome
// Assigning the found palindromic length
// to odd/even length array
R[j][i] = rp;
int k = 1;
while ((R[j][i - k] != rp - k) && (k < rp))
{
R[j][i + k] = Math.min(R[j][i - k],
rp - k);
k++;
}
rp = Math.max(rp - k,0);
i += k;
}
}
// remove 'guards'
s = s.substring(1, s.length()-1);
// Put all obtained palindromes in a hash map to
// find only distinct palindromess
m.put(s.substring(0,1), 1);
for (int i = 1; i < n; i++)
{
for (int j = 0; j <= 1; j++)
for (int rp = R[j][i]; rp > 0; rp--)
m.put(s.substring(i - rp - 1, i - rp - 1
+ 2 * rp + j), 1);
m.put(s.substring(i, i + 1), 1);
}
// printing all distinct palindromes from
// hash map
System.out.println("Below are " + (m.size())
+ " palindrome sub-strings");
for (Map.Entry ii:m.entrySet())
System.out.println(ii.getKey());
}
// Driver program
public static void main(String args[])
{
palindromeSubStrs("abaaa");
}
}
// This code is contributed by Sumit Ghosh
Python
# Python program Find all distinct palindromic sub-strings
# of a given string
# Function to print all distinct palindrome sub-strings of s
def palindromeSubStrs(s):
m = dict()
n = len(s)
# table for storing results (2 rows for odd-
# and even-length palindromes
R = [[0 for x in xrange(n+1)] for x in xrange(2)]
# Find all sub-string palindromes from the given input
# string insert 'guards' to iterate easily over s
s = "@" + s + "#"
for j in xrange(2):
rp = 0 # length of 'palindrome radius'
R[j][0] = 0
i = 1
while i <= n:
# Attempt to expand palindrome centered at i
while s[i - rp - 1] == s[i + j + rp]:
rp += 1 # Incrementing the length of palindromic
# radius as and when we find valid palindrome
# Assigning the found palindromic length to odd/even
# length array
R[j][i] = rp
k = 1
while (R[j][i - k] != rp - k) and (k < rp):
R[j][i+k] = min(R[j][i-k], rp - k)
k += 1
rp = max(rp - k, 0)
i += k
# remove guards
s = s[1:len(s)-1]
# Put all obtained palindromes in a hash map to
# find only distinct palindrome
m[s[0]] = 1
for i in xrange(1,n):
for j in xrange(2):
for rp in xrange(R[j][i],0,-1):
m[s[i - rp - 1 : i - rp - 1 + 2 * rp + j]] = 1
m[s[i]] = 1
# printing all distinct palindromes from hash map
print "Below are " + str(len(m)) + " pali sub-strings"
for i in m:
print i
# Driver program
palindromeSubStrs("abaaa")
# This code is contributed by BHAVYA JAIN and ROHIT SIKKA
C#
// C# program to find all distinct palindrome
// sub-strings of a given string
using System;
using System.Collections.Generic;
class GFG
{
// Function to print all distinct palindrome
// sub-strings of s
public static void palindromeSubStrs(string s)
{
//map m;
Dictionary < string,
int > m = new Dictionary < string,
int > ();
int n = s.Length;
// table for storing results (2 rows for odd-
// and even-length palindromes
int[, ] R = new int[2, n + 1];
// Find all sub-string palindromes from the
// given input string insert 'guards' to
// iterate easily over s
s = "@" + s + "#";
for (int j = 0; j <= 1; j++)
{
int rp = 0; // length of 'palindrome radius'
R[j, 0] = 0;
int i = 1;
while (i <= n)
{
// Attempt to expand palindrome centered
// at i
while (s[i - rp - 1] == s[i + j + rp])
// Incrementing the length of
// palindromic radius as and
// when we find vaid palindrome
rp++;
// Assigning the found palindromic length
// to odd/even length array
R[j, i] = rp;
int k = 1;
while ((R[j, i - k] != rp - k) && k < rp)
{
R[j, i + k] = Math.Min(R[j, i - k], rp - k);
k++;
}
rp = Math.Max(rp - k, 0);
i += k;
}
}
// remove 'guards'
s = s.Substring(1);
// Put all obtained palindromes in a hash map to
// find only distinct palindromess
if (!m.ContainsKey(s.Substring(0, 1)))
m.Add(s.Substring(0, 1), 1);
else
m[s.Substring(0, 1)]++;
for (int i = 1; i < n; i++)
{
for (int j = 0; j <= 1; j++)
for (int rp = R[j, i]; rp > 0; rp--)
{
if (!m.ContainsKey(s.Substring(i - rp - 1, 2 * rp + j)))
m.Add(s.Substring(i - rp - 1, 2 * rp + j), 1);
else
m[s.Substring(i - rp - 1, 2 * rp + j)]++;
}
if (!m.ContainsKey(s.Substring(i, 1)))
m.Add(s.Substring(i, 1), 1);
else
m[s.Substring(i, 1)]++;
}
// printing all distinct palindromes from
// hash map
Console.WriteLine("Below are " + (m.Count));
foreach(KeyValuePair < string, int > ii in m)
Console.WriteLine(ii.Key);
}
// Driver Code
public static void Main(string[] args)
{
palindromeSubStrs("abaaa");
}
}
// This code is contributed by
// sanjeev2552
输出:
Below are 5 palindrome sub-strings
a
aa
aaa
aba
b
类似问题:
计算字符串中的所有回文子字符串