给定一个字符串S ,任务是找到将给定字符串S分成两个非空回文字符串数。
例子:
Input: S = “aaaaa”
Output: 4
Explanation:
Possible Splits: {“a”, “aaaa”}, {“aa”, “aaa”}, {“aaa”, “aa”}, {“aaaa”, “a”}
Input: S = “abacc”
Output: 1
Explanation:
Only possible split is “aba”, “cc”.
朴素的方法:朴素的方法是在每个可能的索引处拆分字符串并检查两个子字符串是否都是回文的。如果是,则增加该索引的计数。打印最终计数。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to check whether the
// substring from l to r is
// palindrome or not
bool isPalindrome(int l, int r,
string& s)
{
while (l <= r) {
// If characters at l and
// r differ
if (s[l] != s[r])
// Not a palindrome
return false;
l++;
r--;
}
// If the string is
// a palindrome
return true;
}
// Function to count and return
// the number of possible splits
int numWays(string& s)
{
int n = s.length();
// Stores the count
// of splits
int ans = 0;
for (int i = 0;
i < n - 1; i++) {
// Check if the two substrings
// after the split are
// palindromic or not
if (isPalindrome(0, i, s)
&& isPalindrome(i + 1,
n - 1, s)) {
// If both are palindromes
ans++;
}
}
// Print the final count
return ans;
}
// Driver Code
int main()
{
string S = "aaaaa";
cout << numWays(S);
return 0;
}
Java
// Java program to implement
// the above approach
class GFG{
// Function to check whether the
// substring from l to r is
// palindrome or not
public static boolean isPalindrome(int l, int r,
String s)
{
while (l <= r)
{
// If characters at l and
// r differ
if (s.charAt(l) != s.charAt(r))
// Not a palindrome
return false;
l++;
r--;
}
// If the string is
// a palindrome
return true;
}
// Function to count and return
// the number of possible splits
public static int numWays(String s)
{
int n = s.length();
// Stores the count
// of splits
int ans = 0;
for(int i = 0; i < n - 1; i++)
{
// Check if the two substrings
// after the split are
// palindromic or not
if (isPalindrome(0, i, s) &&
isPalindrome(i + 1, n - 1, s))
{
// If both are palindromes
ans++;
}
}
// Print the final count
return ans;
}
// Driver Code
public static void main(String args[])
{
String S = "aaaaa";
System.out.println(numWays(S));
}
}
// This code is contributed by SoumikMondal
Python3
# Python3 program to implement
# the above approach
# Function to check whether the
# substring from l to r is
# palindrome or not
def isPalindrome(l, r, s):
while (l <= r):
# If characters at l and
# r differ
if (s[l] != s[r]):
# Not a palindrome
return bool(False)
l += 1
r -= 1
# If the string is
# a palindrome
return bool(True)
# Function to count and return
# the number of possible splits
def numWays(s):
n = len(s)
# Stores the count
# of splits
ans = 0
for i in range(n - 1):
# Check if the two substrings
# after the split are
# palindromic or not
if (isPalindrome(0, i, s) and
isPalindrome(i + 1, n - 1, s)):
# If both are palindromes
ans += 1
# Print the final count
return ans
# Driver Code
S = "aaaaa"
print(numWays(S))
# This code is contributed by divyeshrabadiya07
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Function to check whether the
// substring from l to r is
// palindrome or not
public static bool isPalindrome(int l, int r,
string s)
{
while (l <= r)
{
// If characters at l and
// r differ
if (s[l] != s[r])
// Not a palindrome
return false;
l++;
r--;
}
// If the string is
// a palindrome
return true;
}
// Function to count and return
// the number of possible splits
public static int numWays(string s)
{
int n = s.Length;
// Stores the count
// of splits
int ans = 0;
for(int i = 0; i < n - 1; i++)
{
// Check if the two substrings
// after the split are
// palindromic or not
if (isPalindrome(0, i, s) &&
isPalindrome(i + 1, n - 1, s))
{
// If both are palindromes
ans++;
}
}
// Print the final count
return ans;
}
// Driver Code
public static void Main(string []args)
{
string S = "aaaaa";
Console.Write(numWays(S));
}
}
// This code is contributed by Rutvik
Javascript
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
// Modulo for rolling hash
const int MOD = 1e9 + 9;
// Small prime for rolling hash
const int P = 37;
// Maximum length of string
const int MAXN = 1e5 + 5;
// Stores prefix hash
vector prefixHash(MAXN);
// Stores suffix hash
vector suffixHash(MAXN);
// Stores inverse modulo
// of P for prefix
vector inversePrefix(MAXN);
// Stores inverse modulo
// of P for suffix
vector inverseSuffix(MAXN);
int n;
int power(int x, int y, int mod)
{
// Function to compute
// power under modulo
if (x == 0)
return 0;
int ans = 1;
while (y > 0) {
if (y & 1)
ans = (1LL * ans * x)
% MOD;
x = (1LL * x * x) % MOD;
y >>= 1;
}
return ans;
}
// Precompte hashes for the
// given string
void preCompute(string& s)
{
int x = 1;
for (int i = 0; i 0)
prefixHash[i]
= (prefixHash[i]
+ prefixHash[i - 1])
% MOD;
// Compute inverse modulo
// of P ^ i for division
// using Fermat Little theorem
inversePrefix[i] = power(x, MOD - 2,
MOD);
x = (1LL * x * P) % MOD;
}
x = 1;
// Calculate suffix hash
for (int i = n - 1; i >= 0; i--) {
// Calculate and store hash
suffixHash[i]
= (1LL * int(s[i]
- 'a' + 1)
* x)
% MOD;
if (i 0
? prefixHash[l - 1]
: 0);
h = (h + MOD) % MOD;
h = (1LL * h * inversePrefix[l])
% MOD;
return h;
}
// Function to return Suffix
// Hash of substring
int getSuffixHash(int l, int r)
{
// Calculate suffix hash
// from l to r
int h = suffixHash[l]
- (r < n - 1
? suffixHash[r + 1]
: 0);
h = (h + MOD) % MOD;
h = (1LL * h * inverseSuffix[r])
% MOD;
return h;
}
int numWays(string& s)
{
n = s.length();
// Compute prefix and
// suffix hashes
preCompute(s);
// Stores the number of
// possible splits
int ans = 0;
for (int i = 0;
i < n - 1; i++) {
int preHash = getPrefixHash(0, i);
int sufHash = getSuffixHash(0, i);
// If the substring s[0]...s[i]
// is not palindromic
if (preHash != sufHash)
continue;
preHash = getPrefixHash(i + 1,
n - 1);
sufHash = getSuffixHash(i + 1,
n - 1);
// If the substring (i + 1, n - 1)
// is not palindromic
if (preHash != sufHash)
continue;
// If both are palindromic
ans++;
}
return ans;
}
// Driver Code
int main()
{
string s = "aaaaa";
int ans = numWays(s);
cout << ans << endl;
return 0;
}
输出:
4
时间复杂度: O(N 2 )
高效的方法:可以使用Hashing和Rabin-Karp算法来优化上述方法来存储字符串的Prefix和Suffix Hashes 。请按照以下步骤解决问题:
- 计算给定字符串的前缀和后缀哈希。
- 对于 [1, N – 1] 范围内的每个索引 i,检查两个子串 [0, i – 1] 和 [i, N – 1] 是否是回文。
- 要检查子字符串 [l, r] 是否是回文,只需检查:
PrefixHash[l - r] = SuffixHash[l - r]
- 对于发现两个子串是回文的每个索引 i,增加计数。
- 打印count的最终值。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
// Modulo for rolling hash
const int MOD = 1e9 + 9;
// Small prime for rolling hash
const int P = 37;
// Maximum length of string
const int MAXN = 1e5 + 5;
// Stores prefix hash
vector prefixHash(MAXN);
// Stores suffix hash
vector suffixHash(MAXN);
// Stores inverse modulo
// of P for prefix
vector inversePrefix(MAXN);
// Stores inverse modulo
// of P for suffix
vector inverseSuffix(MAXN);
int n;
int power(int x, int y, int mod)
{
// Function to compute
// power under modulo
if (x == 0)
return 0;
int ans = 1;
while (y > 0) {
if (y & 1)
ans = (1LL * ans * x)
% MOD;
x = (1LL * x * x) % MOD;
y >>= 1;
}
return ans;
}
// Precompte hashes for the
// given string
void preCompute(string& s)
{
int x = 1;
for (int i = 0; i 0)
prefixHash[i]
= (prefixHash[i]
+ prefixHash[i - 1])
% MOD;
// Compute inverse modulo
// of P ^ i for division
// using Fermat Little theorem
inversePrefix[i] = power(x, MOD - 2,
MOD);
x = (1LL * x * P) % MOD;
}
x = 1;
// Calculate suffix hash
for (int i = n - 1; i >= 0; i--) {
// Calculate and store hash
suffixHash[i]
= (1LL * int(s[i]
- 'a' + 1)
* x)
% MOD;
if (i 0
? prefixHash[l - 1]
: 0);
h = (h + MOD) % MOD;
h = (1LL * h * inversePrefix[l])
% MOD;
return h;
}
// Function to return Suffix
// Hash of substring
int getSuffixHash(int l, int r)
{
// Calculate suffix hash
// from l to r
int h = suffixHash[l]
- (r < n - 1
? suffixHash[r + 1]
: 0);
h = (h + MOD) % MOD;
h = (1LL * h * inverseSuffix[r])
% MOD;
return h;
}
int numWays(string& s)
{
n = s.length();
// Compute prefix and
// suffix hashes
preCompute(s);
// Stores the number of
// possible splits
int ans = 0;
for (int i = 0;
i < n - 1; i++) {
int preHash = getPrefixHash(0, i);
int sufHash = getSuffixHash(0, i);
// If the substring s[0]...s[i]
// is not palindromic
if (preHash != sufHash)
continue;
preHash = getPrefixHash(i + 1,
n - 1);
sufHash = getSuffixHash(i + 1,
n - 1);
// If the substring (i + 1, n - 1)
// is not palindromic
if (preHash != sufHash)
continue;
// If both are palindromic
ans++;
}
return ans;
}
// Driver Code
int main()
{
string s = "aaaaa";
int ans = numWays(s);
cout << ans << endl;
return 0;
}
输出:
4
时间复杂度: O(N * log(10 9 ))
空间复杂度: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。