前言
今日练习目的:掌握栈的核心特点后进先出 ,掌握队列核心特点先进先出。栈和队列是后续知识点的重要前置
20:有效括号
题目要求:给定一个只含'(', ')', '{', '}', '[', ']' 的字符串
要求:判断字符串是否有效
核心思路
- 用栈来辅助匹配
栈是一种后进先出的数据结构,适合处理括号匹配问题
当遇到左括号:入栈
当遇到右括号:检查栈顶元素
{栈为空,返回false;栈顶元素与当前右括号不匹配,返回false;匹配,弹出栈顶元素,继续扫描} - 遍历完字符串后
如果栈为空;返回true;如果栈不为空,说明有左括号剩余,返回false}
代码实现
java
import java.util.Stack;
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '(') {
stack.push(')');
} else if (c == '[') {
stack.push(']');
} else if (c == '{') {
stack.push('}');
} else {
// 当前是右括号
if (stack.isEmpty() || stack.pop() != c) {
return false;
}
}
}
return stack.isEmpty();
}
}
总结
栈可以有效解决括号匹配的问题
遇到左括号入栈,遇到右括号匹配栈顶元素
最后判断栈是否为空
394:字符串解码
题目要求:给定一个编码字符串
要求:按规则解码
编码格式为 k[encoded_string],表示 encoded_string 重复 k 次。
你可以假设输入字符串是 有效的,不会有多余空格,且数字 k 是正整数。
可以有嵌套的编码,例如:3[a2[c]]。
核心思路(栈)
遍历字符串
- 遇到数字,计算完整数字
- 遇到[,当前数字和已累加字符串入栈
- 遇到字母,累加当前字符串
- 遇到],弹出栈顶数字和字符串,进行拼接
最用栈处理完,得到完整解码字符串
代码实现
java
Stack<Integer> countStack=new Stack<>();
Stack<StringBuilder> stringStack=new Stack<>();
StringBuilder current=new StringBuilder();
int k=0;
for(char c:s.toCharArray()){
if(Character.isDigit(c)){
k=k*10+(c-'0');//处理多位数字
}else if(c=='['){
countStack.push(k);
stringStack.push(current);
current=new StringBuilder();
k=0;
}else if(c==']'){
StringBuilder decoded=stringStack.pop();
int repeatTimes=countStack.pop();
for(int i=0;i<repeatTimes;i++){
decoded.append(current);
}
current=decoded;
}else{
current.append(c);//普通字母直接累加
}
}
return current.toStinrg();
总结
用两个栈来解决嵌套问题
- countStack(数字栈):存储每个括号前面的重复次数k
- stirngStack(字符串栈):存储括号外点给钱已经累积的字符串。例如 "3[a2[c]]" → 内层 [ 前,已经累积 "a",压入 "a"。
遍历字符串,分情况处理
- 遇到数字,累积到k
k = k * 10 + currentDigit - 遇到[,说明进入字串
把重复次数k压入countStack
把当前累积的字符串current压入stirngStack
重置current为空,开始累积括号里的新内容
重置k=0 - 遇到字母直接加到current
- 遇到],字串结束开始拼接
弹出数字栈repeatTimes
弹出字符串栈decoded(括号外的原字符串)
拼接repeatTimes次当前字串current到decoded
更新current=decoded,作为新字符串继续外层处理
739:每日温度
题目要求:给定一个整数数组temperatures,表示每天温度
要求:返回一个数组answer,其中 answer[i] 是从第 i 天开始,需要等几天才能遇到更高温度。
代码实现
java
int n=temperature.length();
int[] answer=new int[26];
Stack<Integer> stack=new Stack<>();//存储索引
for(int i=0;i<n;i++){
//找到更高温度的天
while(!stack.isEmpty()&&temperature[i]>tempurature[stack.peek()]){
int idx=stack.pop();
answer[idx]=i-idx;
stack.push(i);//存入当前天索引
}
return answer;
总结
问题分析:在一个数组中需要判断元素之间大小顺序。用栈来解决(后进先出)。将每日温度先压入栈中,通过遍历来获取接下来每一天的温度,与栈中温度进行比较。差距天数通过i与栈中存储索引相减得到。