题目
给你一个由 '('、')' 和小写字母组成的字符串 s。
你需要从字符串中删除最少数目的 '(' 或者 ')' (可以删除任意位置的括号),使得剩下的「括号字符串」有效。
请返回任意一个合法字符串。
有效「括号字符串」应当符合以下 任意一条 要求:
空字符串或只包含小写字母的字符串
可以被写作 AB(A 连接 B)的字符串,其中 A 和 B 都是有效「括号字符串」
可以被写作 (A) 的字符串,其中 A 是一个有效的「括号字符串」
示例 1:
输入:s = "lee(t(c)o)de)"
输出:"lee(t(c)o)de"
解释:"lee(t(co)de)" , "lee(t(c)ode)" 也是一个可行答案。
示例 2:
输入:s = "a)b(c)d"
输出:"ab(c)d"
示例 3:
输入:s = "))(("
输出:""
解释:空字符串也是有效的
示例 4:
输入:s = "(a(b(c)d)"
输出:"a(b(c)d)"
提示:
1 <= s.length <= 10^5
s[i] 可能是 '('、')' 或英文小写字母
解析
经典问题——"括号匹配",用栈就可以很容易地解决,具体如下:
比如对于这样一个括号串 )(())((),如果要找到不合法括号的位置,可以这样做:
首先,用一个invalidIndex数组标记无效括号的索引,用一个栈存放所有遍历到的左括号的索引,
然后从前往后扫描这个串,对于第i个括号:
若为(,先进栈(栈中存的是下标),并且标记为无效的,即invalidIndex[i] = true
若为),这时先判断栈是否为空:
若为空,说明右括号)在左括号(之前出现了,那显然是无效括号,即invalidIndex[i] = true;
若不为空,那么这个右括号)和上一个出现的左括号(可以组成合法括号,就从栈中弹出一个元素,将其修正为合法的, 即temp = stack.pop(),invalidIndex[temp] = false
代码
string MinRemoveToMakeValid(string s)
{
Stack<int> bracketIndex = new Stack<int>();
bool[] invalidIndx = new bool[s.Length];
StringBuilder res = new StringBuilder();
for (int i = 0; i < s.Length; i++)
{
if (s[i] == '(')
{
bracketIndex.Push(i);
invalidIndx[i] = true;
}
if (s[i] == ')')
{
if (bracketIndex.Count == 0)
invalidIndx[i] = true;
else
{
invalidIndx[bracketIndex.Pop()] = false;
}
}
}
for (int i = 0; i < s.Length; i++)
{
if (!invalidIndx[i])
res.Append(s[i]);
}
return res.ToString();
}
网友评论