Check if a Regular Bracket Sequence can be formed with concatenation of given strings
Last Updated :
18 Oct, 2021
Given an array arr[] consisting of N strings where each string consists of '(' and ')', the task is to check if a Regular Bracket Sequence can be formed with the concatenation of the given strings or not. If found to be true, then print Yes. Otherwise print No.
Examples:
Input: arr[] = { ")", "()(" }
Output: Yes
Explanation: The valid string is S[1] + S[0] = "()()".
Input: arr[] = { ")(", "()"}
Output: No
Explanation: No valid Regular bracket sequences are possible.
Approach: The given problem can be solved with the help of the Greedy Approach which is based on the following observations:
- If a string contains a consecutive pair of letters ’(’ and ’)’, then removing those two letters does not affect the result.
- By repeating this operation, each S[i] becomes a (possibly empty) string consisting of 0 or more repetition of ’)’, followed by 0 or more repetition of ’(’.
- Then every string can be denoted with two variables A[i] = the number of ’)’, and B[i] = the number of ’(’.
- Maintain a pair vector v[][] to store these values.
- Now, separate there two strings into two separate vectors pos[] and neg[].
- pos[] will store those strings in which the total sum is positive and neg[] with store strings whose total sum is negative.
- Now the optimal way is to concatenate positive strings first then negative strings after that in their increasing order.
Follow the steps below to solve the problem:
- Maintain a pair vector v[][] that will store the values {sum, minimum prefix}, where the sum is calculated by +1 for '(' and -1 for ')' and the minimum prefix is the maximum consecutive ')' in the string.
- Iterate over the range [0. N) using the variable i and perform the following steps:
- Initialize 2 variables sum and pre as 0 to store the sum and minimum prefix for the given string.
- Iterate over the range [0, M) for every character of the string, and if the current character is '(' then increment sum by 1 else decrease it by 1 and set the value of pre as the minimum of pre or sum at every step.
- Set the value of v[I] as { sum, pre }.
- Iterate over the range [0. N) for elements in v[] and for each pair if the sum is positive then store the value {-min_prefix, sum} in pos[] vector otherwise {sum - min_prefix, -sum} in neg[] vector.
- Sort these vectors in increasing order.
- Initialize the variable open as 0.
- Iterate over the range [0. size) where size is the size of the vector pos[] using the iterator variable p and if open - p.first is greater than equal to 0 then add p.second to the variable open. Otherwise, print No and return.
- Initialize the variable negative as 0.
- Iterate over the range [0. size) where size is the size of the vector neg[] using the iterator variable p and if negative - p.first is greater than equal to 0 then add p.second to the variable negative. Otherwise, print No and return.
- If the value of open is not equal to negative, then print No. Otherwise, print Yes.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to check possible RBS from
// the given strings
int checkRBS(vector<string> S)
{
int N = S.size();
// Stores the values {sum, min_prefix}
vector<pair<int, int> > v(N);
// Iterate over the range
for (int i = 0; i < N; ++i) {
string s = S[i];
// Stores the total sum
int sum = 0;
// Stores the minimum prefix
int pre = 0;
for (char c : s) {
if (c == '(') {
++sum;
}
else {
--sum;
}
// Check for minimum prefix
pre = min(sum, pre);
}
// Store these values in vector
v[i] = { sum, pre };
}
// Make two pair vectors pos and neg
vector<pair<int, int> > pos;
vector<pair<int, int> > neg;
// Store values according to the
// mentioned approach
for (int i = 0; i < N; ++i) {
if (v[i].first >= 0) {
pos.push_back(
{ -v[i].second, v[i].first });
}
else {
neg.push_back(
{ v[i].first - v[i].second,
-v[i].first });
}
}
// Sort the positive vector
sort(pos.begin(), pos.end());
// Stores the extra count of
// open brackets
int open = 0;
for (auto p : pos) {
if (open - p.first >= 0) {
open += p.second;
}
// No valid bracket sequence
// can be formed
else {
cout << "No"
<< "\n";
return 0;
}
}
// Sort the negative vector
sort(neg.begin(), neg.end());
// Stores the count of the
// negative elements
int negative = 0;
for (auto p : neg) {
if (negative - p.first >= 0) {
negative += p.second;
}
// No valid bracket sequence
// can be formed
else {
cout << "No\n";
return 0;
}
}
// Check if open is equal to negative
if (open != negative) {
cout << "No\n";
return 0;
}
cout << "Yes\n";
return 0;
}
// Driver Code
int main()
{
vector<string> arr = { ")", "()(" };
checkRBS(arr);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static class pair
{
int first, second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
}
// Function to check possible RBS from
// the given Strings
static int checkRBS(String[] S)
{
int N = S.length;
// Stores the values {sum, min_prefix}
pair []v = new pair[N];
// Iterate over the range
for (int i = 0; i < N; ++i) {
String s = S[i];
// Stores the total sum
int sum = 0;
// Stores the minimum prefix
int pre = 0;
for (char c : s.toCharArray()) {
if (c == '(') {
++sum;
}
else {
--sum;
}
// Check for minimum prefix
pre = Math.min(sum, pre);
}
// Store these values in vector
v[i] = new pair( sum, pre );
}
// Make two pair vectors pos and neg
Vector<pair> pos = new Vector<pair>();
Vector<pair > neg = new Vector<pair>();
// Store values according to the
// mentioned approach
for (int i = 0; i < N; ++i) {
if (v[i].first >= 0) {
pos.add(
new pair( -v[i].second, v[i].first ));
}
else {
neg.add(
new pair( v[i].first - v[i].second,
-v[i].first ));
}
}
// Sort the positive vector
Collections.sort(pos,(a,b)->a.first-b.first);
// Stores the extra count of
// open brackets
int open = 0;
for (pair p : pos) {
if (open - p.first >= 0) {
open += p.second;
}
// No valid bracket sequence
// can be formed
else {
System.out.print("No"
+ "\n");
return 0;
}
}
// Sort the negative vector
Collections.sort(neg,(a,b)->a.first-b.first);
// Stores the count of the
// negative elements
int negative = 0;
for (pair p : neg) {
if (negative - p.first >= 0) {
negative += p.second;
}
// No valid bracket sequence
// can be formed
else {
System.out.print("No\n");
return 0;
}
}
// Check if open is equal to negative
if (open != negative) {
System.out.print("No\n");
return 0;
}
System.out.print("Yes\n");
return 0;
}
// Driver Code
public static void main(String[] args)
{
String []arr = { ")", "()(" };
checkRBS(arr);
}
}
// This code is contributed by shikhasingrajput
Python3
# Python 3 program for the above approach
# Function to check possible RBS from
# the given strings
def checkRBS(S):
N = len(S)
# Stores the values {sum, min_prefix}
v = [0]*(N)
# Iterate over the range
for i in range(N):
s = S[i]
# Stores the total sum
sum = 0
# Stores the minimum prefix
pre = 0
for c in s:
if (c == '('):
sum += 1
else:
sum -= 1
# Check for minimum prefix
pre = min(sum, pre)
# Store these values in vector
v[i] = [sum, pre]
pos = []
neg = []
# Store values according to the
# mentioned approach
for i in range(N):
if (v[i][0] >= 0):
pos.append(
[-v[i][1], v[i][0]])
else:
neg.append(
[v[i][0] - v[i][1],
-v[i][0]])
# Sort the positive vector
pos.sort()
# Stores the extra count of
# open brackets
open = 0
for p in pos:
if (open - p[0] >= 0):
open += p[1]
# No valid bracket sequence
# can be formed
else:
print("No")
return 0
# Sort the negative vector
neg.sort()
# Stores the count of the
# negative elements
negative = 0
for p in neg:
if (negative - p[0] >= 0):
negative += p[1]
# No valid bracket sequence
# can be formed
else:
print("No")
return 0
# Check if open is equal to negative
if (open != negative):
print("No")
return 0
print("Yes")
# Driver Code
if __name__ == "__main__":
arr = [")", "()("]
checkRBS(arr)
# This code is contributed by ukasp.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG{
class pair : IComparable<pair>
{
public int first,second;
public pair(int first, int second)
{
this.first = first;
this.second = second;
}
public int CompareTo(pair p)
{
return this.first - p.first;
}
}
// Function to check possible RBS from
// the given Strings
static int checkRBS(String[] S)
{
int N = S.Length;
// Stores the values {sum, min_prefix}
pair []v = new pair[N];
// Iterate over the range
for (int i = 0; i < N; ++i) {
String s = S[i];
// Stores the total sum
int sum = 0;
// Stores the minimum prefix
int pre = 0;
foreach (char c in s.ToCharArray()) {
if (c == '(') {
++sum;
}
else {
--sum;
}
// Check for minimum prefix
pre = Math.Min(sum, pre);
}
// Store these values in vector
v[i] = new pair( sum, pre );
}
// Make two pair vectors pos and neg
List<pair> pos = new List<pair>();
List<pair > neg = new List<pair>();
// Store values according to the
// mentioned approach
for (int i = 0; i < N; ++i) {
if (v[i].first >= 0) {
pos.Add(
new pair( -v[i].second, v[i].first ));
}
else {
neg.Add(
new pair( v[i].first - v[i].second,
-v[i].first ));
}
}
// Sort the positive vector
pos.Sort();
// Stores the extra count of
// open brackets
int open = 0;
foreach (pair p in pos) {
if (open - p.first >= 0) {
open += p.second;
}
// No valid bracket sequence
// can be formed
else {
Console.Write("No"
+ "\n");
return 0;
}
}
// Sort the negative vector
neg.Sort();
// Stores the count of the
// negative elements
int negative = 0;
foreach (pair p in neg) {
if (negative - p.first >= 0) {
negative += p.second;
}
// No valid bracket sequence
// can be formed
else {
Console.Write("No\n");
return 0;
}
}
// Check if open is equal to negative
if (open != negative) {
Console.Write("No\n");
return 0;
}
Console.Write("Yes\n");
return 0;
}
// Driver Code
public static void Main(String[] args)
{
String []arr = { ")", "()(" };
checkRBS(arr);
}
}
// This code is contributed by 29AjayKumar
JavaScript
<script>
// Javascript program for the above approach
// Function to check possible RBS from
// the given strings
function checkRBS(S) {
let N = S.length;
// Stores the values {sum, min_prefix}
let v = new Array(N);
// Iterate over the range
for (let i = 0; i < N; ++i) {
let s = S[i];
// Stores the total sum
let sum = 0;
// Stores the minimum prefix
let pre = 0;
for (let c of s) {
if (c == "(") {
++sum;
} else {
--sum;
}
// Check for minimum prefix
pre = Math.min(sum, pre);
}
// Store these values in vector
v[i] = [sum, pre];
}
// Make two pair vectors pos and neg
let pos = [];
let neg = [];
// Store values according to the
// mentioned approach
for (let i = 0; i < N; ++i) {
if (v[i][0] >= 0) {
pos.push([-v[i][1], v[i][0]]);
} else {
neg.push([v[i][0] - v[i][1], -v[i][0]]);
}
}
// Sort the positive vector
pos.sort((a, b) => a - b);
// Stores the extra count of
// open brackets
let open = 0;
for (let p of pos) {
if (open - p[0] >= 0) {
open += p[1];
}
// No valid bracket sequence
// can be formed
else {
document.write("No" + "<br>");
return 0;
}
}
// Sort the negative vector
neg.sort((a, b) => a - b);
// Stores the count of the
// negative elements
let negative = 0;
for (let p of neg) {
if (negative - p[0] >= 0) {
negative += p[1];
}
// No valid bracket sequence
// can be formed
else {
document.write("No<br>");
return 0;
}
}
// Check if open is equal to negative
if (open != negative) {
document.write("No<br>");
return 0;
}
document.write("Yes<br>");
return 0;
}
// Driver Code
let arr = [")", "()("];
checkRBS(arr);
// This code is contributed by gfgking.
</script>
Time Complexity: O(N*M + N*log(N)), where M is the maximum length of the string in the array arr[].
Auxiliary Space: O(N)
Similar Reads
Check if a given string can be converted to a Balanced Bracket Sequence Given a string S of size N consisting of '(', ')', and '$', the task is to check whether the given string can be converted into a balanced bracket sequence by replacing every occurrence of $ with either ) or (. A balanced bracket sequence is a sequence where every opening bracket "(" has a correspon
12 min read
Maximum Pairs of Bracket Sequences which can be concatenated to form a Regular Bracket Sequence Given an array arr[] of N strings such that each string consists of characters '(' and ')', the task is to find the maximum number of pairs of strings such that the concatenation of the two strings is a Regular Bracket Sequence. A Regular Bracket Sequence is a string consisting of brackets '(' and '
9 min read
Check whether given string can be generated after concatenating given strings Given three strings str, A and B. The task is to check whether str = A + B or str = B + A where + denotes concatenation. Examples: Input: str = "GeeksforGeeks", A = "Geeksfo", B = "rGeeks" Output: Yes str = A + B = "Geeksfo" + "rGeeks" = "GeeksforGeeks"Input: str = "Delhicapitals", B = "Delmi", C =
11 min read
Check if a string is concatenation of another given string Given two strings str1 and str2 of length N and M respectively, the task is to check if the string str1 can be formed by concatenating the string str2 repetitively or not. Examples: Input: str1 = âabcabcabcâ, str2 = âabcâOutput: YesExplanation: Concatenating the string str2 thrice generates the stri
7 min read
Count distinct regular bracket sequences which are not N periodic Given an integer N, the task is to find the number of distinct bracket sequences that can be formed using 2 * N brackets such that the sequence is not N-periodic. A bracket sequence str of length 2 * N is said to be N-periodic if the sequence can be split into two equal substrings having same regula
8 min read