1.知识点
栈的应用
2.刷题
20.有效的括号
LeetCode链接 20. 有效的括号 - 力扣(LeetCode)
题目描述
方法1:栈
package daimasuixiangshuati.day11_zhanyuduilie;
import java.util.Stack;
/**
* @Author LeiGe
* @Date 2022/10/2
* @Description todo
*/
public class YouXiaoKuoHao20_2 {
/**
* 方法1:遇到左括号,将元素入栈,遇到右括号,弹出栈中元素
* 出栈时候判断是否相等,最后判断栈中元素是否为0:为0表示每对括号都能匹配
*
* @param s
* @return
*/
public boolean isValid(String s) {
if ((s.length() % 2) != 0) {
return false;
}
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(' || c == '[' || c == '{') {
stack.push(c);
} else {
if (stack.isEmpty()) {
return false;
}
Character pop = stack.pop();
if (c == ')') {
if (pop != '(') {
return false;
}
} else if (c == ']') {
if (pop != '[') {
return false;
}
} else {
if (pop != '{') {
return false;
}
}
}
}
return stack.isEmpty();
}
}
时间复杂度:O(N)
空间复杂度:O(N)
方法2:栈
package daimasuixiangshuati.day11_zhanyuduilie;
import java.util.Stack;
/**
* @Author LeiGe
* @Date 2023/10/28
* @Description todo
*/
public class YouXiaoKuoHao20_3 {
/**
* 方法2:遇到左括号,先将对应的右括号压入栈中,
* 遇到右括号,比较当前元素和栈顶元素是否相等,如果相等,弹出元素,如果不相等返回false
*
* @param s
* @return
*/
public boolean isValid(String s) {
int length = s.length();
if (length % 2 != 0) {
return false;
}
Stack<Character> st = new Stack<>();
char ch;
for (int i = 0; i < length; i++) {
ch = s.charAt(i);
if (ch == '(') {
st.push(')');
} else if (ch == '[') {
st.push(']');
} else if (ch == '{') {
st.push('}');
}
// 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
// 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
else if (st.empty() || st.peek() != ch) {
return false;
} else {
st.pop();// st.top() 与 s[i]相等,栈弹出元素
}
}
// 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true
return st.empty();
}
}
时间复杂度:O(N)
空间复杂度:O(N)
1047.删除字符串中的所有相邻重复项
LeetCode链接 1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)
题目描述
方法1:栈
/**
* 方法1:栈,遍历字符串中元素
* 1.如果栈不为空,且栈顶元素和当前遍历元素相同,则弹出栈顶元素,否则将当前元素压入栈中
* 2.最后栈中元素就是处理后的字符串结果
* 3.拿字符串直接作为栈,省去了栈还要转为字符串的操作。
*
* @param s
* @return
*/
public String removeDuplicates(String s) {
// 将 res 当做栈
StringBuffer res = new StringBuffer();
//top为res的长度
int top = -1;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
//当top>0,即栈中有字符时,当前字符如果和栈中相等,弹出栈顶字符,top--
if (top >= 0 && res.charAt(top) == c) {
res.deleteCharAt(top);
top--;
} else {
res.append(c);
top++;
}
}
return res.toString();
}
时间复杂度:O(N)
空间复杂度:O(N)
方法2:双指针
package daimasuixiangshuati.day11_zhanyuduilie;
/**
* @Author LeiGe
* @Date 2023/10/28
* @Description todo
*/
public class ShanChuZiFuChuanZhongDeSuoYouXiangLinChongFuXiang1047_3 {
/**
* 双指针:数组删除重复的元素
* 定义两个指针fast和slow
* fast一直前移 如果slow指针遇到ch[slow] == ch[slow - 1],slow就往后退一步
* 通过用fast指针覆盖slow指针的值来完成去重
*
* @param s
* @return
*/
public String removeDuplicates(String s) {
char[] ch = s.toCharArray();
int fast = 0;
int slow = 0;
while (fast < s.length()) {
//直接用fast指针覆盖slow指针的值
ch[slow] = ch[fast];
//遇到前后相同的值,就跳过,即slow指针后退一步,下次循环就可以直接被覆盖掉了
if (slow > 0 && ch[slow] == ch[slow - 1]) {
slow--;
} else {
slow++;
}
fast++;
}
return new String(ch, 0, slow);
}
}
时间复杂度:O(N)
空间复杂度:O(N)
150.逆波兰表达式求值
LeetCode链接 150. 逆波兰表达式求值 - 力扣(LeetCode)
题目描述
方法1:栈
package daimasuixiangshuati.day11_zhanyuduilie;
import java.util.LinkedList;
/**
* @Author LeiGe
* @Date 2023/10/28
* @Description todo
*/
public class NiBoLanBiaoDaShi150_2 {
/**
* 方法1:栈-遍历字符转
* 1.如果不是运算符,将字符压入栈中
* 2.如果是运算符,弹出两次(弹出两个数字)进行运算,然后压入栈中
*
* @param tokens
* @return
*/
public int evalRPN(String[] tokens) {
LinkedList<Integer> stack = new LinkedList<>();
for (String token : tokens) {
char c = token.charAt(0);
//如果不是运算符(时数字)
if (!isOperator(token)) {
//将数字压栈
stack.push(convertToInteger(token));
} else if (c == '+') {
Integer num2 = stack.pop();
Integer num1 = stack.pop();
stack.push(num1 + num2);
} else if (c == '-') {
Integer num2 = stack.pop();
Integer num1 = stack.pop();
stack.push(num1 - num2);
} else if (c == '*') {
Integer num2 = stack.pop();
Integer num1 = stack.pop();
stack.push(num1 * num2);
} else {
Integer num2 = stack.pop();
Integer num1 = stack.pop();
stack.push(num1 / num2);
}
}
return stack.pop();
}
/**
* 将token转换为Integer
*
* @param token
* @return
*/
private Integer convertToInteger(String token) {
return Integer.valueOf(token);
}
/**
* 判断是不是运算符
*
* @param token
* @return
*/
private boolean isOperator(String token) {
return token.length() == 1 && token.charAt(0) < '0' || token.charAt(0) > '9';
}
}
时间复杂度:O(N)
空间复杂度:O(N)