20. 有效的括号
这道题如果学过栈,很容易就能想到用栈来解决。这里有三种情况:1.左符号多出2.左右符号不匹配3.右符号多出。我们写代码的时候要注意这三种情况。代码如下:
class Solution {
public boolean isValid(String s) {
Stack<Character> st=new Stack<>();
if(s.length()%2!=0){
return false;
}
char[] arr = s.toCharArray();
for(int i=0;i<arr.length;i++){
if(arr[i]=='('){
st.push(')');
}else if(arr[i]=='{'){
st.push('}');
}else if(arr[i]=='['){
st.push(']');
}else if(st.empty()||arr[i]!=st.peek()){
return false;
}else{
st.pop();
}
}
return st.empty();
}
}
代码中,如果我们检测出是左符号,就在栈中弹入右符号,这样的话在处理右符号时,只用看是否匹配即可,不用再做多于处理。
1047. 删除字符串中的所有相邻重复项
这道题跟上一道很像,代码思路也差不多,代码如下:
class Solution {
public String removeDuplicates(String s) {
Stack<Character> st=new Stack<>();
char[] arr=s.toCharArray();
for(int i=0;i<arr.length;i++){
if(st.empty()||arr[i]!=st.peek()){
st.push(arr[i]);
}else{
st.pop();
}
}
StringBuilder sb = new StringBuilder();
while (!st.isEmpty()) {
sb.append(st.pop());
}
String result = sb.reverse().toString();
return result;
}
}
函数先创建一个字符栈,然后把字符串转成字符数组逐个处理。遍历过程中,如果栈为空或者当前字符和栈顶字符不同,就把当前字符压入栈;如果当前字符和栈顶字符相同,说明是一对相邻重复字符,就把栈顶弹出,相当于把这一对一起删除。
遍历结束后,栈中剩下的字符就是最终保留的字符,但此时顺序是“栈底→栈顶”。代码通过不断 pop 把字符加入 StringBuilder,得到的是逆序字符串,因此最后调用 reverse() 反转,恢复为正确顺序并返回。
150. 逆波兰表达式求值
这道题比较难理解,如果学过逆波兰表达式的话会很好写,我们依然是用栈,遇到字符的话就从栈中弹出两个数进行运算再把结果弹入栈中;遇到数字的话就之间弹入栈中。代码如下:
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> st=new Stack<>();
for(int i=0;i<tokens.length;i++){
if(tokens[i].equals("+")||tokens[i].equals("-")||tokens[i].equals("*")||tokens[i].equals("/")){
int num2=st.pop();
int num1=st.pop();
if(tokens[i].equals("+")){
st.push(num1+num2);
}else if(tokens[i].equals("-")){
st.push(num1-num2);
}else if(tokens[i].equals("*")){
st.push(num1*num2);
}else{
st.push(num1/num2);
}
}else{
st.push(Integer.parseInt(tokens[i]));
}
}
return st.peek();
}
}