Recuento de substrings que tienen todos los caracteres distintos

Dada una string str que consiste en letras en minúsculas, la tarea es encontrar el número de posibles substrings (no necesariamente distintas) que consisten solo en caracteres distintos.
Ejemplos: 

Entrada: Str = «gffg» 
Salida:
Explicación: 
Todas las substrings posibles de la string dada son, 
( » g «, » gf «, «gff», «gffg», » f «, «ff», «ffg», “ f ”, “ fg ”, “ g ”) 
Entre ellos, los resaltados consisten solo en caracteres distintos.

Entrada: str = “gfg” 
Salida:
Explicación: 
Todas las substrings posibles de la string dada son, 
( “ g “, “ gf “, “gfg”, “ f “, “ fg “, “ g ”) 
Entre ellas, la resaltado consta únicamente de caracteres distintos. 
 

Enfoque ingenuo: 
el enfoque más simple es generar todas las substrings posibles a partir de la string dada y verificar si cada substring contiene todos los caracteres distintos o no. Si la longitud de la string es N , habrá N*(N+1)/2 posibles substrings. 

Complejidad temporal: O(N 3 )  
Espacio auxiliar: O(1)

Enfoque eficiente: 
el problema se puede resolver en tiempo lineal utilizando la técnica de dos punteros , con la ayuda de contar las frecuencias de los caracteres de la string.

Los pasos detallados para este enfoque son los siguientes: 

  • Considere dos punteros i y j , inicialmente ambos apuntando al primer carácter de la string , es decir i = j = 0 .
  • Inicialice una array Cnt[ ] para almacenar el recuento de caracteres en la substring desde el índice i al j , ambos inclusive.
  • Ahora, siga incrementando el puntero j hasta que se encuentre algún carácter repetido. Mientras incrementa j , agregue el conteo de todas las substrings que terminan en el j -ésimo índice y comienzan en cualquier índice entre i y j a la respuesta. Todas estas substrings contendrán caracteres distintos ya que no se repite ningún carácter en ellas.
  • Si se encuentra algún carácter repetido en la substring entre el índice i al j , para excluir este carácter repetido, siga incrementando el puntero i hasta que se elimine el carácter repetido y siga actualizando la array Cnt[ ] en consecuencia.
  • Continúe este proceso hasta que j llegue al final de la string. Una vez que la string se atraviese por completo, imprima la respuesta.

A continuación se muestra la implementación del enfoque anterior: 

C++

// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to count total
// number of valid substrings
long long int countSub(string str)
{
    int n = (int)str.size();
 
    // Stores the count of
    // substrings
    long long int ans = 0;
 
    // Stores the frequency
    // of characters
    int cnt[26];
 
    memset(cnt, 0, sizeof(cnt));
 
    // Initialised both pointers
    // to beginning of the string
    int i = 0, j = 0;
 
    while (i < n) {
 
        // If all characters in
        // substring from index i
        // to j are distinct
        if (j < n && (cnt[str[j] - 'a']
                      == 0)) {
 
            // Increment count of j-th
            // character
            cnt[str[j] - 'a']++;
 
            // Add all substring ending
            // at j and starting at any
            // index between i and j
            // to the answer
            ans += (j - i + 1);
 
            // Increment 2nd pointer
            j++;
        }
 
        // If some characters are repeated
        // or j pointer has reached to end
        else {
 
            // Decrement count of j-th
            // character
            cnt[str[i] - 'a']--;
 
            // Increment first pointer
            i++;
        }
    }
 
    // Return the final
    // count of substrings
    return ans;
}
 
// Driver Code
int main()
{
    string str = "gffg";
 
    cout << countSub(str);
 
    return 0;
}

Java

// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
 
// Function to count total
// number of valid subStrings
static int countSub(String str)
{
    int n = (int)str.length();
 
    // Stores the count of
    // subStrings
    int ans = 0;
 
    // Stores the frequency
    // of characters
    int []cnt = new int[26];
 
    // Initialised both pointers
    // to beginning of the String
    int i = 0, j = 0;
 
    while (i < n)
    {
 
        // If all characters in
        // subString from index i
        // to j are distinct
        if (j < n &&
           (cnt[str.charAt(j) - 'a'] == 0))
        {
 
            // Increment count of j-th
            // character
            cnt[str.charAt(j) - 'a']++;
 
            // Add all subString ending
            // at j and starting at any
            // index between i and j
            // to the answer
            ans += (j - i + 1);
 
            // Increment 2nd pointer
            j++;
        }
 
        // If some characters are repeated
        // or j pointer has reached to end
        else
        {
 
            // Decrement count of j-th
            // character
            cnt[str.charAt(i) - 'a']--;
 
            // Increment first pointer
            i++;
        }
    }
 
    // Return the final
    // count of subStrings
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "gffg";
 
    System.out.print(countSub(str));
}
}
 
// This code is contributed by amal kumar choubey

Python3

# Python3 program to implement
# the above approach
 
# Function to count total
# number of valid substrings
def countSub(Str):
 
    n = len(Str)
 
    # Stores the count of
    # substrings
    ans = 0
 
    # Stores the frequency
    # of characters
    cnt = 26 * [0]
 
    # Initialised both pointers
    # to beginning of the string
    i, j = 0, 0
 
    while (i < n):
 
        # If all characters in
        # substring from index i
        # to j are distinct
        if (j < n and
           (cnt[ord(Str[j]) - ord('a')] == 0)):
 
            # Increment count of j-th
            # character
            cnt[ord(Str[j]) - ord('a')] += 1
 
            # Add all substring ending
            # at j and starting at any
            # index between i and j
            # to the answer
            ans += (j - i + 1)
 
            # Increment 2nd pointer
            j += 1
 
        # If some characters are repeated
        # or j pointer has reached to end
        else:
 
            # Decrement count of j-th
            # character
            cnt[ord(Str[i]) - ord('a')] -= 1
 
            # Increment first pointer
            i += 1
 
    # Return the final
    # count of substrings
    return ans
 
# Driver code
Str = "gffg"
 
print(countSub(Str))
 
# This code is contributed by divyeshrabadiya07

C#

// C# program to implement
// the above approach
using System;
 
class GFG{
 
// Function to count total
// number of valid subStrings
static int countSub(String str)
{
    int n = (int)str.Length;
 
    // Stores the count of
    // subStrings
    int ans = 0;
 
    // Stores the frequency
    // of characters
    int []cnt = new int[26];
 
    // Initialised both pointers
    // to beginning of the String
    int i = 0, j = 0;
 
    while (i < n)
    {
 
        // If all characters in
        // subString from index i
        // to j are distinct
        if (j < n &&
           (cnt[str[j] - 'a'] == 0))
        {
 
            // Increment count of j-th
            // character
            cnt[str[j] - 'a']++;
 
            // Add all subString ending
            // at j and starting at any
            // index between i and j
            // to the answer
            ans += (j - i + 1);
 
            // Increment 2nd pointer
            j++;
        }
 
        // If some characters are repeated
        // or j pointer has reached to end
        else
        {
 
            // Decrement count of j-th
            // character
            cnt[str[i] - 'a']--;
 
            // Increment first pointer
            i++;
        }
    }
 
    // Return the final
    // count of subStrings
    return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
    String str = "gffg";
 
    Console.Write(countSub(str));
}
}
 
// This code is contributed by amal kumar choubey

Javascript

<script>
 
// JavaScript Program to implement
// the above approach
 
// Function to count total
// number of valid substrings
function countSub(str)
{
    var n = str.length;
 
    // Stores the count of
    // substrings
    var ans = 0;
 
    // Stores the frequency
    // of characters
    var cnt = Array(26).fill(0);
 
    // Initialised both pointers
    // to beginning of the string
    var i = 0, j = 0;
 
    while (i < n) {
 
        // If all characters in
        // substring from index i
        // to j are distinct
        if (j < n && (cnt[str[j].charCodeAt(0) - 'a'.charCodeAt(0)]
                      == 0)) {
 
            // Increment count of j-th
            // character
            cnt[str[j].charCodeAt(0) - 'a'.charCodeAt(0)]++;
 
            // Add all substring ending
            // at j and starting at any
            // index between i and j
            // to the answer
            ans += (j - i + 1);
 
            // Increment 2nd pointer
            j++;
        }
 
        // If some characters are repeated
        // or j pointer has reached to end
        else {
 
            // Decrement count of j-th
            // character
            cnt[str[i].charCodeAt(0) - 'a'.charCodeAt(0)]--;
 
            // Increment first pointer
            i++;
        }
    }
 
    // Return the final
    // count of substrings
    return ans;
}
 
// Driver Code
var str = "gffg";
document.write( countSub(str));
 
</script>
Producción: 

6

 

Complejidad temporal: O(N)  
Espacio auxiliar: O(1)
 

Publicación traducida automáticamente

Artículo escrito por Pawan_29 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 *