栈的应用
应用
应用1:Leetcode 678. 有效的括号字符串
题目
分析
方法一:栈
维护两个栈:\(stack_1\) 和 \(stack_2\),分别保存左括号元素的下标和星号元素的下标。
遍历字符串,
-
遇到一个左括号,就将其下标压入 \(stack_1\);
-
遇到一个左括号,就将其下标压入 \(stack_2\);
-
如果遇到一个右括号
-
如果 \(stack_1\) 不为空,则弹出一个左括号的下标;
-
如果 \(stack_2\) 不为空,则弹出一个星号的下标;
-
如果 \(stack_1\) 和 \(stack_2\) 都为空,则返回 \(False\);
-
-
如果右括号适配完之后,\(stack_1\) 和 \(stack_2\) 中都还有元素
-
如果 \(stack_1\) 和 \(stack_2\) 中的元素个数相等,判断两个栈的栈底的元素组合是否满足有效括号的条件;
-
如果 \(stack_1\) 中的元素个数大于 \(stack_2\),则返回 \(False\) ;
-
如果 \(stack_1\) 中的元素个数小于 \(stack_2\),则返回 \(True\) ;
-
方法二:动态规划
代码实现
方法一:
class Solution {
public boolean checkValidString(String s) {
// 保存左括号的下标
Deque<Integer> stack1 = new LinkedList<>();
// 保存星号的下标
Deque<Integer> stack2 = new LinkedList<>();
int n = s.length();
for (int i = 0; i < n; i++) {
char ch = s.charAt(i);
// 遇到左括号和星号,分别将其入栈; 遇到右括号,则优先弹出一个左括号,否则弹出一个星号
if (ch == '(') {
stack1.push(i);
} else if (ch == '*') {
stack2.push(i);
} else {
if (!stack1.isEmpty()) {
stack1.pop();
} else if (!stack2.isEmpty()) {
stack2.pop();
} else {
return false;
}
}
}
// 如果栈里还剩余星号和左括号
while (! stack1.isEmpty() && ! stack2.isEmpty()) {
int index1 = stack1.pop();
int index2 = stack2.pop();
// 比较左括号和星号的顺序
if (index2 < index1) {
return false;
}
}
return stack1.isEmpty();
}
}
复杂度:
-
时间复杂度:
-
空间复杂度: