👨🏫 平衡括号字符串
给定一个字符串
s
s
s,该字符串的每个字符都是 (
、)
或 #
之一。
你的任务是将
s
s
s 中的每个 #
变换为一个或多个 )
,从而得到一个平衡括号字符串。
不同 #
变换的 )
的数量可以不同。
请你输出为了满足条件,每个 #
所需变换的 )
的数量。
如果方案不唯一,则输出任意合理方案均可。
当一个字符串满足以下所有条件时,该字符串被称为平衡括号字符串:
- 字符串仅由
(
和)
组成。 - 字符串所包含的
(
和)
的数量相同。 - 对于字符串的任意前缀,其所包含的
(
的数量都不少于)
的数量。
输入格式
共一行,一个字符串 s s s。
输入保证
s
s
s 中至少包含一个 #
。
输出格式
如果不存在任何合理方案,则输出 -1
即可。
如果存在合理方案,则按照从左到右的顺序,对于
s
s
s 中的每个 #
,输出一行一个正整数,表示该 #
所需变换的 )
的数量。
如果方案不唯一,则输出任意合理方案均可。
数据范围
前
6
6
6 个测试点满足
1
≤
∣
s
∣
≤
20
1 \le |s| \le 20
1≤∣s∣≤20。
所有测试点满足
1
≤
∣
s
∣
≤
1
0
5
1 \le |s| \le 10^5
1≤∣s∣≤105。
输入样例1:
(((
输出样例1:
1
2
输入样例2:
()((
输出样例2:
2
2
1
① 时刻保证字符串前缀的 左括号数 >= 右括号数
② 贪心:在 ① 的基础上,前边的 # 都转换成最少量的 右括号,最后一个 # 转换成缺失的右括号
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Scanner;
public class Main
{
static int N = 100010;
static int[] ans = new int[N];// #号转右括号的个数
static int cnt;// 记录 # 号的个数
static boolean solve(String s)
{
char[] cc = s.toCharArray();
int t = 0;
int len = cc.length;
for (int i = 0; i < len; i++)
{
char c = cc[i];
if (c == '(')
t++;
else if (c == ')')
t--;
else
{// #
t--;
ans[cnt++] = 1;
}
if (t < 0)// 任何时刻都得保证字符串前缀中的 左括号数 >= 右括号数
return false;
}
ans[cnt - 1] += t;
t = 0;
for (int i = 0, j = 0; i < len; i++)
{
char c = cc[i];
if (c == '(')
t++;
else if (c == ')')
{
t--;
} else
{
t -= ans[j++];
}
if (t < 0)
return false;
}
return true;
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String s = sc.next();
if (!solve(s))
System.out.println(-1);
else
{
for (int i = 0; i < cnt; i++)
System.out.println(ans[i]);
}
}
}