给定一个字符串S 。任务是计算回文子串S1和S2的非重叠对,使得字符串应该是S1[L1…R1]和S2[L2…R2] ,其中0 ≤ L1 ≤ R1 < L2 ≤ R2 < N。任务是计算非重叠回文子串的对数。
例子:
Input: s = “aaa”
Output: 5
All possible pairs are (s[0], s[1]), (s[0], s[2]),
(s[0], s[1, 2]), (s[1], s[2]) and (s[0, 1], s[2])
Input: s = “abacaba”
Output: 36
方法:我们可以使用动态规划来解决上述问题。我们可以最初创建DP表,该表存储substring[i….j]是否为回文。我们维护一个以自下而上的方式填充的布尔值dp[n][n] 。如果子串是回文, dp[i][j] 的值为真,否则为假。要计算 dp[i][j],我们首先检查dp[i+1][j-1]的值,如果该值为真并且s[i]与s[j]相同,那么我们使dp [i][j]正确。否则, dp[i][j] 的值为假。此后可以按照以下步骤获取对数。
- 创建一个left[]数组,其中left[i]存储索引 i 左侧回文数的计数,包括 i。
- 创建一个right[]数组,其中right[i]存储索引 i 右侧的回文数,包括 i。
- 从0迭代到length-1并添加left[i]*right[i+1] 。每个索引的总和将是所需的对数。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define N 100
// Pre-processing function
void pre_process(bool dp[N][N], string s)
{
// Get the size of the string
int n = s.size();
// Initially mark every
// position as false
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
dp[i][j] = false;
}
// For the length
for (int j = 1; j <= n; j++) {
// Iterate for every index with
// length j
for (int i = 0; i <= n - j; i++) {
// If the length is less than 2
if (j <= 2) {
// If characters are equal
if (s[i] == s[i + j - 1])
dp[i][i + j - 1] = true;
}
// Check for equal
else if (s[i] == s[i + j - 1])
dp[i][i + j - 1] = dp[i + 1][i + j - 2];
}
}
}
// Function to return the number of pairs
int countPairs(string s)
{
// Create the dp table initially
bool dp[N][N];
pre_process(dp, s);
int n = s.length();
// Declare the left array
int left[n];
memset(left, 0, sizeof left);
// Declare the right array
int right[n];
memset(right, 0, sizeof right);
// Initially left[0] is 1
left[0] = 1;
// Count the number of palindrome
// pairs to the left
for (int i = 1; i < n; i++) {
for (int j = 0; j <= i; j++) {
if (dp[j][i] == 1)
left[i]++;
}
}
// Initially right most as 1
right[n - 1] = 1;
// Count the number of palindrome
// pairs to the right
for (int i = n - 2; i >= 0; i--) {
right[i] = right[i + 1];
for (int j = n - 1; j >= i; j--) {
if (dp[i][j] == 1)
right[i]++;
}
}
int ans = 0;
// Count the number of pairs
for (int i = 0; i < n - 1; i++)
ans += left[i] * right[i + 1];
return ans;
}
// Driver code
int main()
{
string s = "abacaba";
cout << countPairs(s);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
static int N = 100;
// Pre-processing function
static void pre_process(boolean dp[][], char[] s)
{
// Get the size of the string
int n = s.length;
// Initially mark every
// position as false
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
dp[i][j] = false;
}
}
// For the length
for (int j = 1; j <= n; j++)
{
// Iterate for every index with
// length j
for (int i = 0; i <= n - j; i++)
{
// If the length is less than 2
if (j <= 2)
{
// If characters are equal
if (s[i] == s[i + j - 1])
{
dp[i][i + j - 1] = true;
}
}
// Check for equal
else if (s[i] == s[i + j - 1])
{
dp[i][i + j - 1] = dp[i + 1][i + j - 2];
}
}
}
}
// Function to return the number of pairs
static int countPairs(String s)
{
// Create the dp table initially
boolean dp[][] = new boolean[N][N];
pre_process(dp, s.toCharArray());
int n = s.length();
// Declare the left array
int left[] = new int[n];
// Declare the right array
int right[] = new int[n];
// Initially left[0] is 1
left[0] = 1;
// Count the number of palindrome
// pairs to the left
for (int i = 1; i < n; i++)
{
for (int j = 0; j <= i; j++)
{
if (dp[j][i] == true)
{
left[i]++;
}
}
}
// Initially right most as 1
right[n - 1] = 1;
// Count the number of palindrome
// pairs to the right
for (int i = n - 2; i >= 0; i--)
{
right[i] = right[i + 1];
for (int j = n - 1; j >= i; j--)
{
if (dp[i][j] == true)
{
right[i]++;
}
}
}
int ans = 0;
// Count the number of pairs
for (int i = 0; i < n - 1; i++)
{
ans += left[i] * right[i + 1];
}
return ans;
}
// Driver code
public static void main(String[] args)
{
String s = "abacaba";
System.out.println(countPairs(s));
}
}
// This code contributed by Rajput-Ji
Python3
# Python3 implementation of the approach
N = 100
# Pre-processing function
def pre_process(dp, s):
# Get the size of the string
n = len(s)
# Initially mark every
# position as false
for i in range(n):
for j in range(n):
dp[i][j] = False
# For the length
for j in range(1, n + 1):
# Iterate for every index with
# length j
for i in range(n - j + 1):
# If the length is less than 2
if (j <= 2):
# If characters are equal
if (s[i] == s[i + j - 1]):
dp[i][i + j - 1] = True
# Check for equal
elif (s[i] == s[i + j - 1]):
dp[i][i + j - 1] = dp[i + 1][i + j - 2]
# Function to return the number of pairs
def countPairs(s):
# Create the dp table initially
dp = [[False for i in range(N)]
for j in range(N)]
pre_process(dp, s)
n = len(s)
# Declare the left array
left = [0 for i in range(n)]
# Declare the right array
right = [0 for i in range(n)]
# Initially left[0] is 1
left[0] = 1
# Count the number of palindrome
# pairs to the left
for i in range(1, n):
for j in range(i + 1):
if (dp[j][i] == 1):
left[i] += 1
# Initially right most as 1
right[n - 1] = 1
# Count the number of palindrome
# pairs to the right
for i in range(n - 2, -1, -1):
right[i] = right[i + 1]
for j in range(n - 1, i - 1, -1):
if (dp[i][j] == 1):
right[i] += 1
ans = 0
# Count the number of pairs
for i in range(n - 1):
ans += left[i] * right[i + 1]
return ans
# Driver code
s = "abacaba"
print(countPairs(s))
# This code is contributed by mohit kumar
PHP
= 0; $i--)
{
$right[$i] = $right[$i + 1];
for ($j = $n - 1; $j >= $i; $j--)
{
if ($dp[$i][$j] == 1)
$right[$i]++;
}
}
$ans = 0;
// Count the number of pairs
for ($i = 0; $i < $n - 1; $i++)
$ans += $left[$i] * $right[$i + 1];
return $ans;
}
// Driver code
$s = "abacaba";
echo countPairs($s);
// This code is contributed by Ryuga
?>
C#
// C# implementation of the approach
using System;
class GFG
{
static int N = 100;
// Pre-processing function
static void pre_process(bool [,]dp, char[] s)
{
// Get the size of the string
int n = s.Length;
// Initially mark every
// position as false
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
dp[i,j] = false;
}
}
// For the length
for (int j = 1; j <= n; j++)
{
// Iterate for every index with
// length j
for (int i = 0; i <= n - j; i++)
{
// If the length is less than 2
if (j <= 2)
{
// If characters are equal
if (s[i] == s[i + j - 1])
{
dp[i,i + j - 1] = true;
}
}
// Check for equal
else if (s[i] == s[i + j - 1])
{
dp[i,i + j - 1] = dp[i + 1,i + j - 2];
}
}
}
}
// Function to return the number of pairs
static int countPairs(String s)
{
// Create the dp table initially
bool [,]dp = new bool[N,N];
pre_process(dp, s.ToCharArray());
int n = s.Length;
// Declare the left array
int []left = new int[n];
// Declare the right array
int []right = new int[n];
// Initially left[0] is 1
left[0] = 1;
// Count the number of palindrome
// pairs to the left
for (int i = 1; i < n; i++)
{
for (int j = 0; j <= i; j++)
{
if (dp[j,i] == true)
{
left[i]++;
}
}
}
// Initially right most as 1
right[n - 1] = 1;
// Count the number of palindrome
// pairs to the right
for (int i = n - 2; i >= 0; i--)
{
right[i] = right[i + 1];
for (int j = n - 1; j >= i; j--)
{
if (dp[i,j] == true)
{
right[i]++;
}
}
}
int ans = 0;
// Count the number of pairs
for (int i = 0; i < n - 1; i++)
{
ans += left[i] * right[i + 1];
}
return ans;
}
// Driver code
public static void Main(String[] args)
{
String s = "abacaba";
Console.Write(countPairs(s));
}
}
/* This code contributed by PrinciRaj1992 */
Javascript
输出:
36
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。