检查是否可以使用给定字符串的串联形成正则括号序列
给定一个由N个字符串组成的数组arr[] ,其中每个字符串由'('和')'组成,任务是检查一个正则括号序列 可以由给定字符串的串联形成,也可以不形成。如果发现是真的,则打印Yes 。否则打印No 。
例子:
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.
方法:给定的问题可以借助基于以下观察的贪婪方法来解决:
- 如果字符串包含一对连续的字母'(' 和 ')' ,则删除这两个字母不会影响结果。
- 通过重复此操作,每个S[i]变成一个(可能为空)字符串,由 0 次或多次重复的 ')' 组成,然后是 0 次或多次重复的 '(' 。
- 那么每个字符串都可以用两个变量A[i] = ')' 的数量和 B[i] = '(' 的数量来表示。
- 维护一个对向量v[][]来存储这些值。
- 现在,将两个字符串分成两个单独的向量pos[]和neg[] 。
- pos[]将存储总和为正的字符串,而neg[]将存储总和为负的字符串。
- 现在最佳方法是先连接正字符串,然后按递增顺序连接负字符串。
请按照以下步骤解决问题:
- 维护一个将存储值{sum, minimum prefix}的对向量v[][] ,其中总和由'('的+1和')'的-1计算,最小前缀是最大连续') '在字符串中。
- 迭代范围[0. N)使用变量i并执行以下步骤:
- 将 2 个变量sum和pre初始化为0以存储给定字符串的 sum 和最小前缀。
- 迭代字符串的每个字符的范围[0, M) ,如果当前字符是'('则将sum增加1否则将其减少1并将pre 的值设置为 pre或sum的最小值步。
- 将v[ I ]的值设置为{ sum, pre }。
- 迭代范围[0. N)对于v[]中的元素和每一对,如果总和为正,则将值{-min_prefix, sum}存储在 pos[] 向量中,否则将{sum – min_prefix, -sum} 存储在 neg[] 向量中。
- 按升序对这些向量进行排序。
- 将变量open初始化为0 。
- 迭代范围[0. size)其中size是使用迭代器变量p的向量pos[]的大小,如果open – p.first大于等于0 ,则将p.second添加到变量open中。否则,打印No并返回。
- 将变量负数初始化为0 。
- 迭代范围[0. size)其中size是使用迭代器变量p的向量neg[]的大小,如果为负 - p.first大于等于0 ,则将p.second添加到变量negative 。否则,打印No并返回。
- 如果open的值不等于负数,则打印No 。否则,打印Yes 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check possible RBS from
// the given strings
int checkRBS(vector S)
{
int N = S.size();
// Stores the values {sum, min_prefix}
vector > 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 > pos;
vector > 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 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 pos = new Vector();
Vector neg = new Vector();
// 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
{
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 pos = new List();
List neg = new List();
// 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
输出:
Yes
时间复杂度: O(N*M + N*log(N)),其中 M 是数组 arr[] 中字符串的最大长度。
辅助空间: O(N)