平衡括号字符串
给定一个字符串 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
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]);
}
}
}