📌  相关文章
📜  长度为k的回文子序列数,其中k <= 3

📅  最后修改于: 2021-04-29 13:12:07             🧑  作者: Mango

给定长度为n且正整数为k的字符串S。任务是找到长度为k的回文子序列数,其中k <= 3。

例子:

输入:s =“ aabab”,k = 2输出:4 输入:s =“ aaa”,k = 3输出:1

对于k = 1 ,我们可以轻松地说出字符串的字符数将是答案。
对于k = 2 ,我们可以轻松地制作成对的相同字符,因此我们必须维护字符串中每个字符的计数,然后计算

sum = 0
for character 'a' to 'z'
  cnt = count(characater)
  sum = sum + cnt*(cnt-1)/2
sum is the answer.

现在,随着k的增加,变得很难找到。如何找到k = 3的答案?因此,我们的想法是看到长度为3的回文将采用TZT格式,因此我们必须维护两个矩阵,一个矩阵用于计算每个字符的前缀和,另一个矩阵用于计算字符串中每个字符的后缀和。
索引为i的字符T的前缀总和为L [T] [i],T在[0,i](索引)范围内出现的次数。
后缀总和在索引一个字符T IR [T]已经发生在[I,N – 1]的范围内(指数)。
两个矩阵都将是26 * n,并且可以以复杂度O(26 * n)预先计算这两个矩阵,其中n是字符串的长度。
现在如何计算子序列?考虑一下:对于索引,我假设一个字符X在[0,i – 1]范围内出现n1次,在[i +1,n – 1]范围内出现n2次,那么该字符的答案将为n1 * n2即L [X] [i-1] * R [X] [i + 1],这将给出格式Xs [i] -X的子序列数,其中s [i]是第i个字符指数。因此,对于每个指数,您都必须计算出

L[X][i-1] * R[X][i+1], 
where i is the range [1, n-2]  and 
      X will be from 'a' to 'z'

以下是此方法的实现:

C++
// CPP program to count number of subsequences of
// given length.
#include 
#define MAX 100
#define MAX_CHAR 26
using namespace std;
  
// Precompute the prefix and suffix array.
void precompute(string s, int n, int l[][MAX], 
                                 int r[][MAX])
{
    l[s[0] - 'a'][0] = 1;
  
    // Precompute the prefix 2D array
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < MAX_CHAR; j++) 
            l[j][i] += l[j][i - 1];        
  
        l[s[i] - 'a'][i]++;
    }
  
    r[s[n - 1] - 'a'][n - 1] = 1;
  
    // Precompute the Suffix 2D array.
    for (int i = n - 2; i >= 0; i--) {
        for (int j = 0; j < MAX_CHAR; j++) 
            r[j][i] += r[j][i + 1];       
  
        r[s[i] - 'a'][i]++;
    }
}
  
// Find the number of palindromic subsequence of 
// length k
int countPalindromes(int k, int n, int l[][MAX], 
                                   int r[][MAX])
{
    int ans = 0;
  
    // If k is 1.
    if (k == 1) {
        for (int i = 0; i < MAX_CHAR; i++) 
            ans += l[i][n - 1];  
        return ans;
    }
  
    // If k is 2
    if (k == 2) {
  
        // Adding all the products of prefix array
        for (int i = 0; i < MAX_CHAR; i++)             
            ans += ((l[i][n - 1] * (l[i][n - 1] - 1)) / 2);
        return ans;
    }
  
    // For k greater than 2. Adding all the products
    // of value of prefix and suffix array.
    for (int i = 1; i < n - 1; i++) 
        for (int j = 0; j < MAX_CHAR; j++)             
            ans += l[j][i - 1] * r[j][i + 1];  
  
    return ans;
}
  
// Driven Program
int main()
{
    string s = "aabab";
    int k = 2;
    int n = s.length();
    int l[MAX_CHAR][MAX] = { 0 }, r[MAX_CHAR][MAX] = { 0 };
    precompute(s, n, l, r);
    cout << countPalindromes(k, n, l, r) << endl;
    return 0;
}


Java
// Java program to count number of subsequences of
// given length.
class GFG
{
      
static final int MAX=100;
static final int MAX_CHAR=26;
  
// Precompute the prefix and suffix array.
static void precompute(String s, int n, int l[][], 
                                int r[][])
{
    l[s.charAt(0) - 'a'][0] = 1;
  
    // Precompute the prefix 2D array
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < MAX_CHAR; j++) 
            l[j][i] += l[j][i - 1];     
  
        l[s.charAt(i) - 'a'][i]++;
    }
  
    r[s.charAt(n - 1) - 'a'][n - 1] = 1;
  
    // Precompute the Suffix 2D array.
    for (int i = n - 2; i >= 0; i--) {
        for (int j = 0; j < MAX_CHAR; j++) 
            r[j][i] += r[j][i + 1];     
  
        r[s.charAt(i) - 'a'][i]++;
    }
}
  
// Find the number of palindromic subsequence of 
// length k
static int countPalindromes(int k, int n, int l[][], 
                                            int r[][])
{
    int ans = 0;
  
    // If k is 1.
    if (k == 1) {
        for (int i = 0; i < MAX_CHAR; i++) 
            ans += l[i][n - 1]; 
          
        return ans;
    }
  
    // If k is 2
    if (k == 2) {
  
        // Adding all the products of prefix array
        for (int i = 0; i < MAX_CHAR; i++)             
            ans += ((l[i][n - 1] * (l[i][n - 1] - 1)) / 2);
          
        return ans;
    }
  
    // For k greater than 2. Adding all the products
    // of value of prefix and suffix array.
    for (int i = 1; i < n - 1; i++) 
        for (int j = 0; j < MAX_CHAR; j++)             
            ans += l[j][i - 1] * r[j][i + 1]; 
  
    return ans;
} 
      
// Driver code 
public static void main (String[] args)
{
    String s = "aabab";
    int k = 2;
    int n = s.length();
    int l[][]=new int[MAX_CHAR][MAX];
    int r[][]=new int[MAX_CHAR][MAX];
      
    precompute(s, n, l, r);
      
    System.out.println(countPalindromes(k, n, l, r));
}
}
  
// This code is contributed by Anant Agarwal.


Python3
# Python3 program to count number of 
# subsequences of given length.
  
MAX = 100
MAX_CHAR = 26
  
# Precompute the prefix and suffix array.
def precompute(s, n, l, r):
    l[ord(s[0]) - ord('a')][0] = 1
  
    # Precompute the prefix 2D array
    for i in range(1, n):
        for j in range(MAX_CHAR):
            l[j][i] += l[j][i - 1]
          
        l[ord(s[i]) - ord('a')][i] += 1
  
    r[ord(s[n - 1]) - ord('a')][n - 1] = 1
  
    # Precompute the Suffix 2D array.
    k = n - 2
    while(k >= 0):
        for j in range(MAX_CHAR):
            r[j][k] += r[j][k + 1]
        r[ord(s[k]) - ord('a')][k] += 1
        k -= 1
  
# Find the number of palindromic 
# subsequence of length k
def countPalindromes(k, n, l, r):
    ans = 0
  
    # If k is 1.
    if (k == 1):
        for i in range(MAX_CHAR):
            ans += l[i][n - 1]
        return ans
  
    # If k is 2
    if (k == 2):
          
        # Adding all the products of 
        # prefix array
        for i in range(MAX_CHAR):
            ans += ((l[i][n - 1] * (l[i][n - 1] - 1)) / 2)
        return ans
      
    # For k greater than 2. Adding all 
    # the products of value of prefix 
    # and suffix array.
    for i in range(1, n - 1):
        for j in range(MAX_CHAR):
            ans += l[j][i - 1] * r[j][i + 1]
    return ans
  
# Driven Program
s = "aabab"
k = 2
n = len(s)
  
l = [[0 for x in range(MAX)] for y in range(MAX_CHAR)]
r = [[0 for x in range(MAX)] for y in range(MAX_CHAR)]
  
precompute(s, n, l, r)
print (countPalindromes(k, n, l, r))
  
  
# This code is written by Sachin Bisht


C#
// C# program to count number of 
// subsequences of given length.
using System;
class GFG {
      
static int MAX=100;
static int MAX_CHAR=26;
  
// Precompute the prefix
// and suffix array.
static void precompute(string s, int n, 
                    int [,]l, int [,]r)
{
    l[s[0] - 'a',0] = 1;
  
    // Precompute the 
    // prefix 2D array
    for (int i = 1; i < n; i++) 
    {
        for (int j = 0; j < MAX_CHAR; j++) 
            l[j, i] += l[j,i - 1];     
  
        l[s[i] - 'a',i]++;
    }
  
    r[s[n - 1] - 'a',n - 1] = 1;
  
    // Precompute the Suffix 2D array.
    for (int i = n - 2; i >= 0; i--) 
    {
        for (int j = 0; j < MAX_CHAR; j++) 
            r[j, i] += r[j,i + 1];     
  
        r[s[i] - 'a',i]++;
    }
}
  
// Find the number of palindromic
// subsequence of length k
static int countPalindromes(int k, int n, 
                      int [,]l, int [,]r)
{
    int ans = 0;
  
    // If k is 1.
    if (k == 1)
    {
        for (int i = 0; i < MAX_CHAR; i++) 
            ans += l[i,n - 1]; 
          
        return ans;
    }
  
    // If k is 2
    if (k == 2) {
  
        // Adding all the products
        // of prefix array
        for (int i = 0; i < MAX_CHAR; i++)             
            ans += ((l[i,n - 1] * 
                    (l[i,n - 1] - 1)) / 2);
          
        return ans;
    }
  
    // For k greater than 2. 
    // Adding all the products
    // of value of prefix and 
    // suffix array.
    for (int i = 1; i < n - 1; i++) 
        for (int j = 0; j < MAX_CHAR; j++)             
            ans += l[j,i - 1] * r[j, i + 1]; 
  
    return ans;
} 
      
// Driver code 
public static void Main ()
{
    string s = "aabab";
    int k = 2;
    int n = s.Length;
    int [,]l=new int[MAX_CHAR,MAX];
    int [,]r=new int[MAX_CHAR,MAX];
      
    precompute(s, n, l, r);
      
    Console.Write(countPalindromes(k, n, l, r));
}
}
  
// This code is contributed by Nitin Mittal.


PHP
= 0; $i--) 
    {
        for ($j = 0; $j < $MAX_CHAR; $j++) 
            $r[$j][$i] += $r[$j][$i + 1];     
  
        $r[ord($s[$i]) - ord('a')][$i]++;
    }
}
  
// Find the number of palindromic 
// subsequence of length k
function countPalindromes($k, $n, &$l, &$r)
{
    global $MAX, $MAX_CHAR;
    $ans = 0;
  
    // If k is 1.
    if ($k == 1) 
    {
        for ($i = 0; $i < $MAX_CHAR; $i++) 
            $ans += $l[$i][$n - 1]; 
        return $ans;
    }
  
    // If k is 2
    if ($k == 2) 
    {
  
        // Adding all the products of 
        // prefix array
        for ($i = 0; $i < $MAX_CHAR; $i++)             
            $ans += (($l[$i][$n - 1] *
                     ($l[$i][$n - 1] - 1)) / 2);
        return $ans;
    }
  
    // For k greater than 2. Adding all 
    // the products of value of prefix 
    // and suffix array.
    for ($i = 1; $i < $n - 1; $i++) 
        for ($j = 0; $j < $MAX_CHAR; $j++)             
            $ans += $l[$j][$i - 1] * 
                    $r[$j][$i + 1]; 
  
    return $ans;
}
  
// Driver Code
$s = "aabab";
$k = 2;
$n = strlen($s);
$l = array_fill(0, $MAX_CHAR, 
     array_fill(0, $MAX, NULL)); 
$r = array_fill(0, $MAX_CHAR, 
     array_fill(0, $MAX, NULL));
precompute($s, $n, $l, $r);
echo countPalindromes($k, $n, $l, $r) . "\n";
  
// This code is contributed by ita_c
?>


输出:

4