📜  计算循环正则括号的所有索引

📅  最后修改于: 2021-10-26 06:50:44             🧑  作者: Mango

给定一个长度为N的字符串S ,仅由左括号 ‘ ( ‘ 和右括号 ‘ ) ‘ 组成。任务是找到所有索引 ‘ K ‘ 使得S[K…N-1] + S[0…K-1]是一个正则括号。

例子:

朴素的方法:朴素的方法是在每个可能的索引(比如K )处拆分给定的字符串str并检查str[K, N-1] + str[0, K-1]是否是回文。如果是,则打印K 的特定值。
时间复杂度: O(N 2 )
辅助空间: O(1)
有效的方法:我们的想法是观察,如果在任何索引(比如K )处,右括号的计数大于左括号的计数,那么该索引是拆分字符串的可能索引。以下是步骤:

  1. 只有当左括号的数量必须等于右括号的数量时,才能进行分区。否则我们不能形成任何分区来平衡括号。
  2. 创建一个字符串长度的辅助数组(比如aux[] )。
  3. 如果任何索引处的字符(比如i )是‘(‘然后将aux[i]更新为 1否则将 strong>aux[i] 更新为 -1,则遍历给定的字符串。
  4. 上述辅助数组中最小元素的频率是使S[K…N-1] + S[0…K-1]成为正则括号字符串所需的分裂次数(例如在索引K 处)。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find all indices which
// cyclic shift leads to get
// balanced parenthesis
int countCyclicShifts(string& S, int n)
{
    int aux[n] = { 0 };
 
    // Create auxiliary array
    for (int i = 0; i < n; ++i) {
        if (S[i] == '(')
            aux[i] = 1;
        else
            aux[i] = -1;
    }
 
    // Finding prefix sum and
    // minimum element
    int mn = aux[0];
 
    for (int i = 1; i < n; ++i) {
        aux[i] += aux[i - 1];
 
        // Update the minimum element
        mn = min(mn, aux[i]);
    }
 
    // ChecK if count of '(' and
    // ')' are equal
    if (aux[n - 1] != 0)
        return 0;
 
    // Find count of minimum
    // element
    int count = 0;
 
    // Find the frequency of mn
    for (int i = 0; i < n; ++i) {
        if (aux[i] == mn)
            count++;
    }
 
    // Return the count
    return count;
}
 
// Driver Code
int main()
{
    // Given string S
    string S = ")()(";
 
    int N = S.length();
 
    // Function Call
    cout << countCyclicShifts(S, N);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function to find all indices which
// cyclic shift leads to get
// balanced parenthesis
static int countCyclicShifts(String S, int n)
{
     
    // Create auxiliary array
    int[] aux = new int[n];
     
    for(int i = 0; i < n; ++i)
    {
       if (S.charAt(i) == '(')
           aux[i] = 1;
       else
           aux[i] = -1;
    }
     
    // Finding prefix sum and
    // minimum element
    int mn = aux[0];
     
    for(int i = 1; i < n; ++i)
    {
       aux[i] += aux[i - 1];
        
       // Update the minimum element
       mn = Math.min(mn, aux[i]);
    }
     
    // Check if count of '(' and ')'
    // are equal
    if (aux[n - 1] != 0)
        return 0;
     
    // Find count of minimum
    // element
    int count = 0;
     
    // Find the frequency of mn
    for(int i = 0; i < n; ++i)
    {
       if (aux[i] == mn)
           count++;
    }
     
    // Return the count
    return count;
}
 
// Driver code
public static void main(String[] args)
{
     
    // Given string S
    String S = ")()(";
         
    // length of the string S
    int N = S.length();
         
    System.out.print(countCyclicShifts(S, N));
}
}
 
// This code is contributed by sanjoy_62


Python3
# Python3 program for the above approach
 
# Function to find all indices which
# cyclic shift leads to get
# balanced parenthesis
def countCyclicShifts(S, n):
     
    aux = [0 for i in range(n)]
 
    # Create auxiliary array
    for i in range(0, n):
        if (S[i] == '('):
            aux[i] = 1
        else:
            aux[i] = -1
 
    # Finding prefix sum and
    # minimum element
    mn = aux[0]
 
    for i in range(1, n):
        aux[i] += aux[i - 1]
 
        # Update the minimum element
        mn = min(mn, aux[i])
 
    # ChecK if count of '(' and
    # ')' are equal
    if (aux[n - 1] != 0):
        return 0
 
    # Find count of minimum
    # element
    count = 0
 
    # Find the frequency of mn
    for i in range(0, n):
        if (aux[i] == mn):
            count += 1
 
    # Return the count
    return count
 
# Driver Code
 
# Given string S
S = ")()("
N = len(S)
 
# Function call
print(countCyclicShifts(S, N))
 
# This code is contributed by Sanjit_Prasad


C#
// C# program for the above approach
using System;
 
class GFG{
     
// Function to find all indices which
// cyclic shift leads to get
// balanced parenthesis
static int countCyclicShifts(string S, int n)
{
     
    // Create auxiliary array
    int[] aux = new int[n];
     
    for(int i = 0; i < n; ++i)
    {
        if (S[i] == '(')
            aux[i] = 1;
        else
            aux[i] = -1;
    }
     
    // Finding prefix sum and
    // minimum element
    int mn = aux[0];
     
    for(int i = 1; i < n; ++i)
    {
        aux[i] += aux[i - 1];
             
        // Update the minimum element
        mn = Math.Min(mn, aux[i]);
    }
     
    // Check if count of '(' and ')'
    // are equal
    if (aux[n - 1] != 0)
        return 0;
     
    // Find count of minimum
    // element
    int count = 0;
     
    // Find the frequency of mn
    for(int i = 0; i < n; ++i)
    {
        if (aux[i] == mn)
            count++;
    }
     
    // Return the count
    return count;
}
 
// Driver code
public static void Main(string[] args)
{
     
    // Given string S
    string S = ")()(";
         
    // length of the string S
    int N = S.Length;
         
    Console.Write(countCyclicShifts(S, N));
}
}
 
// This code is contributed by rutvik_56


Javascript


输出:
2

时间复杂度: O(N) ,其中 N 是字符串的长度。
辅助空间: O(N) ,其中 N 是字符串的长度。