写题目的时候,一般用双端队列来模拟栈。
双端队列: Deque<> queue = new LinkedList<>(); // 添加到队尾 deque.offerLast(1); // 推荐,返回true/false // 添加到队首 deque.offerFirst(2); // 推荐 // 移除队首 first = deque.pollFirst(); // 推荐,返回null // 移除队尾 last = deque.pollLast(); // 推荐 // 查看队首 first = deque.peekFirst(); // 推荐,返回null // 查看队尾 last = deque.peekLast(); // 推荐 deque.isEmpty(); // 是否为空 deque.size(); // 元素个数 deque.contains(1); // 是否包含 deque.clear(); // 清空 deque.removeFirstOccurrence(1); // 移除第一个出现的1
有效的括号
遇到右括号就和栈顶的判断下,如果匹配就出栈,最后看下栈是不是空。数据结构Map和Stack。
class Solution {
public boolean isValid(String s) {
if(s.length() <= 1 || s.length() % 2 == 1){
return false;
}
Map<Character, Character> mp = new HashMap<>();
mp.put('(',')');
mp.put('[',']');
mp.put('{','}');
Stack<Character> st = new Stack<>();
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
// 如果是左括号
if(mp.get(c) != null){
st.push(c);
}else{
// 右括号 判断情况
if(st.isEmpty() || mp.get(st.peek()) != c){
return false;
}
st.pop();
}
}
return st.isEmpty();
}
}
最小栈
需用辅助栈存对应的最小值。当一个元素要入栈时,我们取当前辅助栈的栈顶存储的最小值,与当前元素比较得出最小值,将这个最小值插入辅助栈中。
class MinStack {
Deque<Integer> st;
Deque<Integer> minst;
public MinStack() {
st = new LinkedList<Integer>();
minst = new LinkedList<Integer>();
minst.offerLast(Integer.MAX_VALUE);
}
public void push(int val) {
st.offerLast(val);
minst.offerLast(Math.min(minst.peekLast(), val));
}
public void pop() {
st.pollLast();
minst.pollLast();
}
public int top() {
return st.peekLast();
}
public int getMin() {
return minst.peekLast();
}
}
字符串编码
递归。模拟题,看代码理解比较方便。关联知识点:StringBuilder的用法。
class Solution {
int index = 0;
public String decodeString(String s) {
return dfs(s);
}
public String dfs(String s){
StringBuilder res = new StringBuilder();
// 当匹配到]时退出当层递归
while(index < s.length() && s.charAt(index) != ']'){
// 如果是数字的话
int num = 0;
if(s.charAt(index) <='9' && s.charAt(index) >= '0'){
num = getNum(s);
// 略过左右括号 递归调用
index++;
String inner = dfs(s);
index++;
// 拼凑出结果
for(int i = 0; i < num; i++){
res.append(inner);
}
}else{
// 左括号前面一定有数字 所以非数字的情况只能是字母
res.append(s.charAt(index));
index++;
}
}
return res.toString();
}
public int getNum(String s){
int num = 0;
while(index <s.length() && s.charAt(index) <='9' && s.charAt(index) >= '0' ){
num = num * 10 + s.charAt(index) - '0';
index++;
}
return num;
}
}
每日温度
单调栈。
单调栈:遍历列表,从第一个开始,比上一个小就入栈,否则就出栈直到栈顶元素大于当前的列表元素或者栈为空,维持一个单调递减的栈。
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int n = temperatures.length;
int[] res = new int[n];
// 栈里存的是索引
Deque<Integer> dq = new LinkedList<>();
int index = 0;
for(int i = 0; i<n; i++){
int temp = temperatures[i];
// 当前的温度大于栈顶的温度 可以更新了
// 一个例子 索引里面可能存的是 0(60)、1(55)、2(50),遇到了3(57)
// 不断退出索引 直到遇到0(60)
while(!dq.isEmpty() && temp > temperatures[dq.peekLast()]){
// 栈顶的索引
int preIndex = dq.pollLast();
res[preIndex] = i - preIndex;
}
// 栈顶的温度 大于当前的温度 索引入栈
dq.offerLast(i);
}
return res;
}
}