Recuento máximo de 0 entre dos 1 en un rango determinado para consultas Q

Dada una string binaria S de tamaño N y una array 2D Q[][] de consultas que consta de M pares de la forma {L, R} , la tarea para cada consulta es encontrar el número máximo de 0 que se encuentran entre dos 1 en el rango [L, R] .

Ejemplos:

Entrada: S = “1001010”, Q[][] = {{0, 4}, {0, 5}}
Salida: 2 3
Explicación: 
Las consultas se realizan de la siguiente manera:

  1. Consulta (0, 4): Imprima 2 ya que hay un máximo de 2 0 entre los índices 0 y 3 en la substring sobre el rango [0, 4], es decir, «10010». 
  2. Consulta (0, 5): Imprima 3 ya que hay un máximo de 3 0 entre los índices 0 y 5 en la substring sobre el rango [0, 5], es decir, «100101».

Entrada: S = “111”, Q[][] = {{0, 2}}
Salida: 0

Enfoque ingenuo: el enfoque más simple para resolver el problema dado es atravesar la array dada de consultas Q[][] y para cada consulta imprimir el número máximo de 0 entre dos pares de 1 iterando sobre el rango [L, R] .

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

Enfoque eficiente: el enfoque anterior se puede optimizar utilizando el concepto de array de suma de prefijos que dará como resultado el cálculo de tiempo constante de una consulta. Siga los pasos a continuación para resolver el problema:

  • Inicialice dos arrays , digamos leftBound[] y rightBound[], para almacenar el conteo de 0 que están a la derecha de los 1 más recientes y el conteo de 0 que quedan con los 1 más recientes , respectivamente.
  • Inicialice dos variables, digamos count y total para actualizar las arrays leftBound[] y rightBound[] .
  • Recorra la string dada S y si el carácter actual es ‘ 1 ‘ entonces asigne el valor de curr a la variable total . De lo contrario, incremente los totales en 1 y luego asigne el valor de curr a rightBound[i] .
  • Actualice el valor de curr y totales a 0 .
  • Recorra la string en el orden inverso y en cada iteración si el carácter actual es ‘ 1 ‘ entonces actualice el valor de curr al total . De lo contrario, incremente el valor de total en 1 y luego actualice el valor de curr a lefttBound[i] .
  • Después de completar los pasos anteriores, recorra la array dada de consultas Q[][] y para cada consulta imprima el valor de (LímiteIzquierdo[Q[i][0]] + LímiteDerecho[Q[i][1]] – total) como el número máximo resultante de 0s .

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

C++

#include <iostream>
using namespace std;
 
// Function to count the number of
// 0s lying between the two 1s for
// each query
void countOsBetween1s(string S, int N, int Q[][2])
{
 
    // Stores count of 0's that are
    // right to the most recent 1's
    int leftBound[N];
 
    // Stores count of 0's that are
    // left to the most recent 1's
    int rightBound[N];
 
    // Stores the count of zeros
    // in a prefix/suffix of array
    int count = 0;
 
    // Stores the count of total 0s
    int total = 0;
 
    // Traverse the string S
    for (int i = 0; i < N; i++) {
 
        // If current character is
        // '1'
        if (S[i] == '1') {
            count = total;
        }
 
        // Otherwise
        else if (S[i] == '0') {
            total++;
        }
 
        // Update the rightBound[i]
        rightBound[i] = count;
    }
 
    // Update count and total to 0
    count = 0;
    total = 0;
 
    // Traverse the string S in
    // reverse manner
    for (int i = N - 1; i >= 0; i--) {
 
        // If current character is
        // '1'
        if (S[i] == '1') {
            count = total;
        }
 
        // Otherwise
        else if (S[i] == '0') {
            total++;
        }
 
        // Update the leftBound[i]
        leftBound[i] = count;
    }
 
    // Traverse given query array
    for (int q = 0; q < 2; q++) {
 
        int L = Q[q][0];
        int R = Q[q][1];
 
        // Update the value of count
        count = leftBound[L] + rightBound[R] - total;
 
        // Print the count as the
        // result to the current
        // query [L, R]
        cout << count << " ";
    }
}
 
// Driver Code
int main()
{
 
    string S = "1001010";
    int Q[][2] = { { 0, 4 }, { 0, 5 } };
    int N = S.length();
    countOsBetween1s(S, N, Q);
    return 0;
}
 
// This code is contributed by Potta Lokesh

Java

// Java program for the above approach
 
import java.lang.*;
import java.util.*;
 
class GFG {
 
    // Function to count the number of
    // 0s lying between the two 1s for
    // each query
    static void countOsBetween1s(
        String S, int N, int[][] Q)
    {
 
        // Stores count of 0's that are
        // right to the most recent 1's
        int[] leftBound = new int[N];
 
        // Stores count of 0's that are
        // left to the most recent 1's
        int[] rightBound = new int[N];
 
        // Stores the count of zeros
        // in a prefix/suffix of array
        int count = 0;
 
        // Stores the count of total 0s
        int total = 0;
 
        // Traverse the string S
        for (int i = 0; i < N; i++) {
 
            // If current character is
            // '1'
            if (S.charAt(i) == '1') {
                count = total;
            }
 
            // Otherwise
            else if (S.charAt(i) == '0') {
                total++;
            }
 
            // Update the rightBound[i]
            rightBound[i] = count;
        }
 
        // Update count and total to 0
        count = 0;
        total = 0;
 
        // Traverse the string S in
        // reverse manner
        for (int i = N - 1; i >= 0; i--) {
 
            // If current character is
            // '1'
            if (S.charAt(i) == '1') {
                count = total;
            }
 
            // Otherwise
            else if (S.charAt(i) == '0') {
                total++;
            }
 
            // Update the leftBound[i]
            leftBound[i] = count;
        }
 
        // Traverse given query array
        for (int q = 0; q < Q.length; q++) {
 
            int L = Q[q][0];
            int R = Q[q][1];
 
            // Update the value of count
            count = leftBound[L] + rightBound[R] - total;
 
            // Print the count as the
            // result to the current
            // query [L, R]
            System.out.print(count + " ");
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String S = "1001010";
        int Q[][] = { { 0, 4 }, { 0, 5 } };
        int N = S.length();
        countOsBetween1s(S, N, Q);
    }
}

Python3

# Function to count the number of
# 0s lying between the two 1s for
# each query
def countOsBetween1s(S, N, Q):
 
    # Stores count of 0's that are
    # right to the most recent 1's
    leftBound = [0]*N
 
    # Stores count of 0's that are
    # left to the most recent 1's
    rightBound = [0]*N
 
    # Stores the count of zeros
    # in a prefix/suffix of array
    count = 0
 
    # Stores the count of total 0s
    total = 0
 
    # Traverse the string S
    for i in range(N):
 
        # If current character is
        # '1'
        if (S[i] == '1'):
            count = total
 
        # Otherwise
        elif (S[i] == '0'):
            total += 1
 
        # Update the rightBound[i]
        rightBound[i] = count
 
    # Update count and total to 0
    count = 0
    total = 0
 
    # Traverse the string S in
    # reverse manner
    for i in range(N - 1, -1, -1):
 
        # If current character is
        # '1'
        if (S[i] == '1'):
            count = total
 
        # Otherwise
        elif (S[i] == '0'):
            total += 1
 
        # Update the leftBound[i]
        leftBound[i] = count
 
    # Traverse given query array
    for q in range(2):
 
        L = Q[q][0]
        R = Q[q][1]
 
        # Update the value of count
        count = leftBound[L] + rightBound[R] - total
 
        # Print the count as the
        # result to the current
        # query [L, R]
        print(count, end=" ")
 
 
# Driver Code
if __name__ == "__main__":
 
    S = "1001010"
    Q = [[0, 4], [0, 5]]
    N = len(S)
    countOsBetween1s(S, N, Q)
 
    # This code is contributed by ukasp.

C#

// C# program for the above approach
using System;
 
public class GFG {
 
    // Function to count the number of
    // 0s lying between the two 1s for
    // each query
    static void countOsBetween1s(
        String S, int N, int[,] Q)
    {
 
        // Stores count of 0's that are
        // right to the most recent 1's
        int[] leftBound = new int[N];
 
        // Stores count of 0's that are
        // left to the most recent 1's
        int[] rightBound = new int[N];
 
        // Stores the count of zeros
        // in a prefix/suffix of array
        int count = 0;
 
        // Stores the count of total 0s
        int total = 0;
 
        // Traverse the string S
        for (int i = 0; i < N; i++) {
 
            // If current character is
            // '1'
            if (S[i] == '1') {
                count = total;
            }
 
            // Otherwise
            else if (S[i] == '0') {
                total++;
            }
 
            // Update the rightBound[i]
            rightBound[i] = count;
        }
 
        // Update count and total to 0
        count = 0;
        total = 0;
 
        // Traverse the string S in
        // reverse manner
        for (int i = N - 1; i >= 0; i--) {
 
            // If current character is
            // '1'
            if (S[i] == '1') {
                count = total;
            }
 
            // Otherwise
            else if (S[i] == '0') {
                total++;
            }
 
            // Update the leftBound[i]
            leftBound[i] = count;
        }
 
        // Traverse given query array
        for (int q = 0; q < Q.GetLength(0); q++) {
 
            int L = Q[q,0];
            int R = Q[q,1];
 
            // Update the value of count
            count = leftBound[L] + rightBound[R] - total;
 
            // Print the count as the
            // result to the current
            // query [L, R]
            Console.Write(count + " ");
        }
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        String S = "1001010";
        int [,]Q = { { 0, 4 }, { 0, 5 } };
        int N = S.Length;
        countOsBetween1s(S, N, Q);
    }
}
 
// This code is contributed by Amit Katiyar

Javascript

<script>
 
// Function to count the number of
// 0s lying between the two 1s for
// each query
function countOsBetween1s(S, N, Q) {
 
    // Stores count of 0's that are
    // right to the most recent 1's
    let leftBound = new Array(N);
 
    // Stores count of 0's that are
    // left to the most recent 1's
    let rightBound = new Array(N);
 
    // Stores the count of zeros
    // in a prefix/suffix of array
    let count = 0;
 
    // Stores the count of total 0s
    let total = 0;
 
    // Traverse the string S
    for (let i = 0; i < N; i++) {
 
        // If current character is
        // '1'
        if (S[i] == '1') {
            count = total;
        }
 
        // Otherwise
        else if (S[i] == '0') {
            total++;
        }
 
        // Update the rightBound[i]
        rightBound[i] = count;
    }
 
    // Update count and total to 0
    count = 0;
    total = 0;
 
    // Traverse the string S in
    // reverse manner
    for (let i = N - 1; i >= 0; i--) {
 
        // If current character is
        // '1'
        if (S[i] == '1') {
            count = total;
        }
 
        // Otherwise
        else if (S[i] == '0') {
            total++;
        }
 
        // Update the leftBound[i]
        leftBound[i] = count;
    }
 
    // Traverse given query array
    for (let q = 0; q < 2; q++) {
 
        let L = Q[q][0];
        let R = Q[q][1];
 
        // Update the value of count
        count = leftBound[L] + rightBound[R] - total;
 
        // Print the count as the
        // result to the current
        // query [L, R]
        document.write(count + " ");
    }
}
 
// Driver Code
 
let S = "1001010";
let Q = [[0, 4], [0, 5]];
let N = S.length;
countOsBetween1s(S, N, Q);
 
 
// This code is contributed by gfgking
</script>
Producción: 

2 3

 

Complejidad temporal: O(N + M)
Espacio auxiliar: O(N)

Publicación traducida automáticamente

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