一. 括号的合法性
- 单括号
- 记录左右括号个数,当右括号个数大于左括号个数,返回 false
- 多括号
public boolean isValid(String s) {
HashMap<Character, Character> map = new HashMap<>();
map.put('(', ')');
map.put('[', ']');
map.put('{', '}');
Stack<Character> stack = new Stack<>();
for(char c : s.toCharArray()) {
if(map.containsKey(c)) {
stack.add(c);
}else {
if(!stack.isEmpty() && c == map.get(stack.peek())) {
stack.pop();
}else {
return false;
}
}
}
return stack.isEmpty();
}
二. 单调栈
- 单调栈:每次新元素入栈后,栈内元素保持有序(单调递增或单调递减)
- 下一个更大元素(leedcode-496)
- 给定一个数组,返回一个等长的数组,对应索引存储着下一个更大元素,如果没有,就存-1
- 下一个更大元素Ⅱ(leedcode-503)
- 处理循环数组
public int[] nextGreaterElements(int[] nums) {
Stack<Integer> stack = new Stack<>();
int n = nums.length;
int[] res = new int[n];
for(int i = 2 * n - 1; i >= 0; i--){
while(!stack.isEmpty() && stack.peek() <= nums[i % n]){
stack.pop();
}
res[i % n] = stack.isEmpty() ? -1 : stack.peek();
stack.push(nums[i % n]);
}
//System.out.println(Arrays.toString(res));
return res;
}
三. 最小栈(剑指-30)
- 设计一个可以在常数时间内检索到最小值的栈
- 空间复杂度 O(n)
- 借助一个辅助栈,在插入元素的时候存入最小值
- 例:(-2, 0, -3) 辅助栈:(-2, -2, -3)
- 空间复杂度O(1) - 需要限制数字范围(正 - 负 会溢出)
- 借助一个变量,保存最小值min,栈中存入的是(当前值 - min)
- pop():如果栈顶元素 < 0,说明min即为要删除的元素,则需要修改min = min - s.peek()
- peek():如果栈顶元素 < 0,说明min即为原本的栈顶元素,返回min即可,否则返回min + s.peek()
- 例:(-2, 0 ,-3)栈:(0, 2, -1)min:-2 -> -2 -> -3
四. 栈的压入弹出(剑指-31)
- 问题描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。
- 借助辅助栈模拟 push, pop操作,如果最终栈为空,则返回true
- push:按照压栈序列的顺序执行
- pop:每次入栈后,循环判断 “栈顶元素 == 弹出序列的当前元素(通过一个变量记录位置)” 是否成立,将符合弹出序列顺序的栈顶元素全部弹出