Número de subsecuencias palindrómicas de longitud k donde k <= 3 – Part 1

Dada una string S de longitud n y un entero positivo k. La tarea es encontrar el número de subsecuencias palindrómicas de longitud k donde k <= 3.

Ejemplos: 

Input : s = "aabab", k = 2
Output : 4

Input : s = "aaa", k = 3
Output : 1

Para k = 1 , podemos decir fácilmente que el número de caracteres en la string será la respuesta. 
Para k = 2 , podemos hacer fácilmente pares de los mismos caracteres, por lo que debemos mantener el recuento de cada carácter en la string y luego calcular 

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

Ahora, a medida que aumenta k, se vuelve difícil de encontrar. ¿Cómo encontrar la respuesta para k = 3 ? Entonces, la idea es ver que los palíndromos de longitud 3 tendrán el formato TZT, por lo que debemos mantener dos arrays, una para calcular la suma del prefijo de cada carácter y otra para calcular la suma del sufijo de cada carácter en la string. 

La suma del prefijo para un carácter T en el índice i es L[T][i], es decir, el número de veces que T ha ocurrido en el rango [0, i](índices). 
La suma de sufijos para un carácter T en el índice i es R[T][i] ha ocurrido en el rango [i, n – 1](índices). 

Ambas arrays serán 26*n y se pueden precalcular ambas arrays en complejidad O(26*n) donde n es la longitud de la string.

Ahora, ¿cómo calcular la subsecuencia? Piense en esto: 
para un índice, supongo que un carácter X aparece n1 veces en el rango [0, i – 1] y n2 veces en el rango [i + 1, n – 1], entonces la respuesta para este carácter será n1 * n2, es decir, L[X][i-1] * R[X][i + 1], esto dará el recuento de subsecuencias del formato Xs[i]-X donde s[i] es el carácter en i-th índice. Así que para cada índice i tendrás que contar el producto de

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

A continuación se muestra la implementación de este enfoque: 

C++

// CPP program to count number of subsequences of
// given length.
#include <bits/stdc++.h>
#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

<?php
// PHP program to count number of
// subsequences of given length.
$MAX = 100;
$MAX_CHAR = 26;
 
// Precompute the prefix and suffix array.
function precompute($s, $n, &$l, &$r)
{
    global $MAX, $MAX_CHAR;
    $l[ord($s[0]) - ord('a')][0] = 1;
 
    // Precompute the prefix 2D array
    for ($i = 1; $i < $n; $i++)
    {
        for ($j = 0; $j < $MAX_CHAR; $j++)
            $l[$j][$i] += $l[$j][$i - 1];    
 
        $l[ord($s[$i]) - ord('a')][$i]++;
    }
 
    $r[ord($s[$n - 1]) - ord('a')][$n - 1] = 1;
 
    // Precompute the Suffix 2D array.
    for ($i = $n - 2; $i >= 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
?>

Javascript

<script>
// Javascript program to count number of subsequences of
// given length.
     
let MAX=100;
let MAX_CHAR=26;
 
// Precompute the prefix and suffix array.
function precompute(s,n,l,r)
{
        l[s[0].charCodeAt(0) - 'a'.charCodeAt(0)][0] = 1;
   
    // Precompute the prefix 2D array
    for (let i = 1; i < n; i++) {
        for (let j = 0; j < MAX_CHAR; j++)
            l[j][i] += l[j][i - 1];    
   
        l[s[i].charCodeAt(0) - 'a'.charCodeAt(0)][i]++;
    }
   
    r[s[n-1].charCodeAt(0) - 'a'.charCodeAt(0)][n - 1] = 1;
   
    // Precompute the Suffix 2D array.
    for (let i = n - 2; i >= 0; i--) {
        for (let j = 0; j < MAX_CHAR; j++)
            r[j][i] += r[j][i + 1];    
   
        r[s[i].charCodeAt(0) - 'a'.charCodeAt(0)][i]++;
    }
}
 
// Find the number of palindromic subsequence of
// length k
function countPalindromes(k,n,l,r)
{
    let ans = 0;
   
    // If k is 1.
    if (k == 1) {
        for (let 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 (let 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 (let i = 1; i < n - 1; i++)
        for (let j = 0; j < MAX_CHAR; j++)            
            ans += l[j][i - 1] * r[j][i + 1];
   
    return ans;
}
 
// Driver code
let s = "aabab";
let k = 2;
let n = s.length;
let l=new Array(MAX_CHAR);
let r= new Array(MAX_CHAR);
for(let i=0;i<MAX_CHAR;i++)
{
    l[i]=new Array(MAX);
    r[i]=new Array(MAX);
    for(let j=0;j<MAX;j++)
    {
        l[i][j]=0;
        r[i][j]=0;
    }
}
precompute(s, n, l, r);
document.write(countPalindromes(k, n, l, r));
     
    // This code is contributed by avanitrachhadiya2155
</script>
Producción

4

Publicación traducida automáticamente

Artículo escrito por anuj0503 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *