📌  相关文章
📜  Q 查询的给定范围内两个 1 之间的最大 0 计数

📅  最后修改于: 2022-05-13 01:56:05.362000             🧑  作者: Mango

Q 查询的给定范围内两个 1 之间的最大 0 计数

给定一个大小为N的二进制字符串S和一个由M对形式为{L, R}的查询组成的二维数组Q[][] ,每个查询的任务是找到位于两个1之间的0的最大数量在[L, R]范围内。

例子:

朴素方法:解决给定问题的最简单方法是遍历给定的查询数组Q[][] ,并为每个查询通过迭代范围[L, R]打印任意两对1之间的最大0数.

时间复杂度: O(N*M)
辅助空间: O(1)

高效方法:上述方法可以使用前缀和数组的概念进行优化,这将导致查询的恒定时间计算。请按照以下步骤解决问题:

  • 初始化两个数组leftBound[]rightBound[] 分别存储最近1的右侧0的计数和最近1左侧的0的计数。
  • 初始化两个变量,比如counttotal以更新数组leftBound[]rightBound[]
  • 遍历给定的字符串S ,如果当前字符为 ' 1 ',则将curr的值赋给变量total 。否则,将总计1 ,然后将curr的值分配给rightBound[i]
  • currtotals的值更新为0
  • 以相反的顺序遍历字符串,如果当前字符为 ' 1 ',则在每次迭代中将curr的值更新为total 。否则,将total的值增加1 ,然后将curr的值更新为 lefttBound[i]
  • 完成上述步骤后,遍历给定的查询数组Q[][]并为每个查询打印(leftBound[Q[i][0]] + rightBound[Q[i][1]] – total)的值作为结果的最大数量0

下面是上述方法的实现:

C++
#include 
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


输出:
2 3

时间复杂度: O(N + M)
辅助空间: O(N)