题目介绍

题解
需要两个栈分别存储左括号和星号的下标(为了最后判断用星号作为有括号时是否符合题意)。
从左到右遍历字符串,进行如下操作:
-
如果遇到左括号,则将当前下标存入左括号栈。
-
如果遇到星号,则将当前下标存入星号栈。
-
如果遇到右括号,则需要有一个左括号或星号和右括号匹配,由于星号也可以看成右括号或者空字符串,因此当前的右括号应优先和左括号匹配,没有左括号时和星号匹配:
-
如果左括号栈不为空,则从左括号栈弹出栈顶元素;
-
如果左括号栈为空且星号栈不为空,则从星号栈弹出栈顶元素;
-
如果左括号栈和星号栈都为空,则没有字符可以和当前的右括号匹配,返回 false。
-
遍历结束之后,左括号栈和星号栈可能还有元素。为了将每个左括号匹配,需要将星号看成右括号,且每个左括号必须出现在其匹配的星号之前。当两个栈都不为空时,每次从左括号栈和星号栈分别弹出栈顶元素,对应左括号下标和星号下标,判断是否可以匹配,匹配的条件是左括号下标小于星号下标,如果左括号下标大于星号下标则返回 false。
最终判断左括号栈是否为空。如果左括号栈为空,则左括号全部匹配完毕,剩下的星号都可以看成空字符串,此时 s 是有效的括号字符串,返回 true。如果左括号栈不为空,则还有左括号无法匹配,此时 s 不是有效的括号字符串,返回 false。
代码如下:
class Solution {
public boolean checkValidString(String s) {
Stack<Integer> leftStack = new Stack<>(); // 存左括号的下标
Stack<Integer> starStack = new Stack<>(); // 存星号的下标
int n = s.length();
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 asteriskIndex = starStack.pop();
if (leftIndex > asteriskIndex) { // 左括号下标大于星号下标不符合条件
return false;
}
}
return leftStack.isEmpty();
}
}
1254

被折叠的 条评论
为什么被折叠?



