📌  相关文章
📜  查询到在给定范围内的二进制字符串的字符翻转

📅  最后修改于: 2021-04-21 22:16:35             🧑  作者: Mango

给定一个二进制字符串str和一个二维数组Q [] [],表示形式为{L,R}的查询。在每个查询中,切换索引[L,R]中存在的二进制字符串的所有字符。任务是通过执行所有查询来打印二进制字符串。

例子:

天真的方法:解决问题的最简单方法是遍历所有查询数组并切换索引[L,R]中的所有字符。最后,打印二进制字符串。

时间复杂度: O(M * N),其中N表示二进制字符串的长度
辅助空间: O(1)

高效方法:为了优化上述方法,其思想是使用Prefix Sum数组技术。请按照以下步骤解决问题:

  • 初始化一个数组,例如prefixCnt [],以存储二进制字符串的i元素被切换的次数的值。
  • 遍历查询Q [] []数组,并为每个查询更新prefixCnt [Q [i] [0]] + = 1prefixCnt [Q [i] [1] + 1]-= 1的值
  • 遍历prefixCnt []数组,并获取prefixCnt []数组的前缀总和。
  • 最后,遍历二进制字符串并检查prefixCnt [i]%2 == 1的值。如果发现是正确的,则切换二进制字符串的i元素。

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to find the binary string by
// performing all the given queries
string toggleQuery(string str, int Q[][2],
                   int M)
{
 
    // Stores length of the string
    int N = str.length();
 
    // prefixCnt[i]: Stores number
    // of times str[i] toggled by
    // performing all the queries
    int prefixCnt[N + 1] = { 0 };
 
    for (int i = 0; i < M; i++) {
 
        // Update prefixCnt[Q[i][0]]
        prefixCnt[Q[i][0]] += 1;
 
        // Update prefixCnt[Q[i][1] + 1]
        prefixCnt[Q[i][1] + 1] -= 1;
    }
 
    // Calculate prefix sum of prefixCnt[i]
    for (int i = 1; i <= N; i++) {
        prefixCnt[i] += prefixCnt[i - 1];
    }
 
    // Traverse prefixCnt[] array
    for (int i = 0; i < N; i++) {
 
        // If ith element toggled
        // odd number of times
        if (prefixCnt[i] % 2) {
 
            // Toggled i-th element
            // of binary string
            str[i] = '1' - str[i] + '0';
        }
    }
    return str;
}
 
// Driver Code
int main()
{
    string str = "101010";
    int Q[][2] = { { 0, 1 }, { 2, 5 },
                   { 2, 3 }, { 1, 4 },
                   { 0, 5 } };
    int M = sizeof(Q) / sizeof(Q[0]);
    cout << toggleQuery(str, Q, M);
}


Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
 
// Function to find the binary
// String by performing all the
// given queries
static String toggleQuery(char[] str,
                          int Q[][], int M)
{
  // Stores length of the String
  int N = str.length;
 
  // prefixCnt[i]: Stores number
  // of times str[i] toggled by
  // performing all the queries
  int prefixCnt[] = new int[N + 1];
 
  for (int i = 0; i < M; i++)
  {
    // Update prefixCnt[Q[i][0]]
    prefixCnt[Q[i][0]] += 1;
 
    // Update prefixCnt[Q[i][1] + 1]
    prefixCnt[Q[i][1] + 1] -= 1;
  }
 
  // Calculate prefix sum of
  // prefixCnt[i]
  for (int i = 1; i <= N; i++)
  {
    prefixCnt[i] += prefixCnt[i - 1];
  }
 
  // Traverse prefixCnt[] array
  for (int i = 0; i < N; i++)
  {
    // If ith element toggled
    // odd number of times
    if (prefixCnt[i] % 2 == 1)
    {
      // Toggled i-th element
      // of binary String
      str[i] = (char)('1' -
                str[i] + '0');
 
    }
  }
  return String.valueOf(str);
}
 
// Driver Code
public static void main(String[] args)
{
  String str = "101010";
  int Q[][] = {{0, 1}, {2, 5},
               {2, 3}, {1, 4},
               {0, 5}};
  int M = Q.length;
  System.out.print(
  toggleQuery(str.toCharArray(),
              Q, M));
}
}
 
// This code is contributed by shikhasingrajput


Python3
# Python3 program to implement
# the above approach
 
# Function to find the binary by
# performing all the given queries
def toggleQuery(strr, Q, M):
     
    strr = [i for i in strr]
 
    # Stores length of the strring
    N = len(strr)
 
    # prefixCnt[i]: Stores number
    # of times strr[i] toggled by
    # performing all the queries
    prefixCnt = [0] * (N + 1)
 
    for i in range(M):
 
        # Update prefixCnt[Q[i][0]]
        prefixCnt[Q[i][0]] += 1
 
        # Update prefixCnt[Q[i][1] + 1]
        prefixCnt[Q[i][1] + 1] -= 1
 
    # Calculate prefix sum of prefixCnt[i]
    for i in range(1, N + 1):
        prefixCnt[i] += prefixCnt[i - 1]
 
    # Traverse prefixCnt[] array
    for i in range(N):
 
        # If ith element toggled
        # odd number of times
        if (prefixCnt[i] % 2):
 
            # Toggled i-th element
            # of binary strring
            strr[i] = (chr(ord('1') -
                           ord(strr[i]) +
                           ord('0')))
                            
    return "".join(strr)
 
# Driver Code
if __name__ == '__main__':
     
    strr = "101010";
    Q = [ [ 0, 1 ],[ 2, 5 ],
          [ 2, 3 ],[ 1, 4 ],
          [ 0, 5 ] ]
    M = len(Q)
 
    print(toggleQuery(strr, Q, M))
 
# This code is contributed by mohit kumar 29


C#
// C# program to implement
// the above approach
using System;
class GFG{
 
// Function to find the binary
// String by performing all the
// given queries
static String toggleQuery(char[] str,
                          int [,]Q ,
                          int M)
{
  // Stores length of the String
  int N = str.Length;
 
  // prefixCnt[i]: Stores number
  // of times str[i] toggled by
  // performing all the queries
  int []prefixCnt = new int[N + 1];
 
  for (int i = 0; i < M; i++)
  {
    // Update prefixCnt[Q[i,0]]
    prefixCnt[Q[i, 0]] += 1;
 
    // Update prefixCnt[Q[i,1] + 1]
    prefixCnt[Q[i, 1] + 1] -= 1;
  }
 
  // Calculate prefix sum of
  // prefixCnt[i]
  for (int i = 1; i <= N; i++)
  {
    prefixCnt[i] += prefixCnt[i - 1];
  }
 
  // Traverse prefixCnt[] array
  for (int i = 0; i < N; i++)
  {
    // If ith element toggled
    // odd number of times
    if (prefixCnt[i] % 2 == 1)
    {
      // Toggled i-th element
      // of binary String
      str[i] = (char)('1' -
                str[i] + '0');
 
    }
  }
  return String.Join("", str);
}
 
// Driver Code
public static void Main(String[] args)
{
  String str = "101010";
  int [,]Q = {{0, 1}, {2, 5},
              {2, 3}, {1, 4},
              {0, 5}};
  int M = Q.GetLength(0);
  Console.Write(toggleQuery(str.ToCharArray(),
                            Q, M));
}
}
 
// This code is contributed by shikhasingrajput


输出:
111000







时间复杂度: O(N + | Q |),其中N是二进制字符串的长度。
辅助空间: O(N)