题目:有效的括号字符串
给你一个只包含三种字符的字符串,支持的字符类型分别是 '('、')' 和 '*'。请你检验这个字符串是否为有效字符串,如果是有效字符串返回 true 。
有效字符串符合如下规则:
- 任何左括号
'('必须有相应的右括号')'。 - 任何右括号
')'必须有相应的左括号'('。 - 左括号
'('必须在对应的右括号之前')'。 '*'可以被视为单个右括号')',或单个左括号'(',或一个空字符串。- 一个空字符串也被视为有效字符串。
示例 1:
输入: s = "()"
输出: true
示例 2:
输入: s = "(*)"
输出: true
示例 3:
输入: s = "(*))"
输出: true
提示:
1 <= s.length <= 100s[i]为'('、')'或'*'
解题思路
先创建两个栈,一个用来存放左括号下标,一个用来存放星号下标,这是因为星号可以替代左括号或者右括号,还可以代表空串.所以一个栈是解决不了的,然后遍历这个s,遇到左括号就放到左括号栈中,遇到星号就放到星号栈中
若遇到右括号,我们先从左括号栈中取左括号,若左括号栈中为空再从星号栈中进行取出让其替代左括号,若存在一个右括号,但是左括号栈和*号栈都为空则说明不能匹配成功.再将所有的右括号匹配完后,可能存在左括号栈和星号栈不为空的情况,这个时候呢我们的星号只能变成右括号,只有这样才能与左括号进行匹配,所以我们可以比较左括号和星号的下标,
若星号的下标小于左括号的下标则说明出现这种情况 )(,就不符合题意,直接返回false. 最后判断左括号栈是否为空即可.若为空则说明匹配成功.
代码实现
public boolean checkValidString(String s) {
int n = s.length();
Deque < Integer > leftStack = new LinkedList < > ();
Deque < Integer > starStack = new LinkedList < > ();
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
if (c == '(') {
leftStack.push(i);
} else if (c == '*') {
starStack.push(i);
} else {
if (!leftStack.isEmpty()) {
leftStack.pop();
} else if (!starStack.isEmpty()) {
starStack.pop();
} else {
return false;
}
}
}
while (!leftStack.isEmpty() && !starStack.isEmpty()) {
int leftIndex = leftStack.pop();
int starIndex = starStack.pop();
if (leftIndex > starIndex) return false;
}
return leftStack.isEmpty();
}
运行结果
复杂度分析
- 空间复杂度:O(n)
- 时间复杂度:O(n)
在掘金(JUEJIN) 一起分享知识, Keep Learning!