- 1、栈(官解)
使用一个栈存储操作数,从左到右遍历逆波兰表达式,进行如下操作:
如果遇到操作数,则将操作数入栈;
如果遇到运算符,则将两个操作数出栈,其中先出栈的是右操作数,后出栈的是左操作数,使用运算符对两个操作数进行运算,将运算得到的新操作数入栈。
整个逆波兰表达式遍历完毕之后,栈内只有一个元素,该元素即为逆波兰表达式的值。
public int evalRPN(String[] tokens) {
Deque<Integer> stack = new LinkedList<Integer>();
int n=tokens.length;
for(int i=0;i<n;i++){
String t=tokens[i];
if(t.equals("+") || t.equals("-") || t.equals("*") || t.equals("/")){
int num2=stack.pop();
int num1=stack.pop();
switch(t){
case "+":
stack.push(num1+num2);
break;
case "-":
stack.push(num1-num2);
break;
case "*":
stack.push(num1*num2);
break;
case "/":
stack.push(num1/num2);
break;
default:
}
}else{
stack.push(Integer.parseInt(t));
}
}
return stack.pop();
}
}
- 2、用数组模拟栈(还是直接用栈比较容易理解)
class Solution {
public int evalRPN(String[] tokens) {
int n=tokens.length;
int[] stack = new int[n];
int index=-1;
for(int i=0;i<n;i++){
String t=tokens[i];
switch(t){
case "+":
index--;
stack[index] += stack[index + 1];
break;
case "-":
index--;
stack[index] -= stack[index + 1];
break;
case "*":
index--;
stack[index] *= stack[index + 1];
break;
case "/":
index--;
stack[index] /= stack[index + 1];
break;
default:
index++;
stack[index]=Integer.parseInt(t);
}
}
return stack[index];
}
}
- 单调队列,超级妙
和卡尔的视频www.bilibili.com/video/BV1XS… 更好理解
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> deque= new LinkedList<>();
int[] res=new int[nums.length-k+1];
//未形成窗口
for(int i=0;i<k;i++){
while(!deque.isEmpty() && deque.peekLast() < nums[i]){//队列前面的元素比当前push进来的元素小的时候,直接带走。单调队列即单调递增或递减.
deque.removeLast();
}
deque.addLast(nums[i]);//第一个值加进去
}
res[0] = deque.peekFirst();//第一个窗口的最大值就是队首
//形成窗口后
for(int i=k;i<nums.length;i++){//移动窗口
if(deque.peekFirst()==nums[i-k]){//如果当前数组中要pop的元素等于队首元素,就pop队首元素,如果不是就说明还没轮到pop当前窗口中的最大值
deque.removeFirst();
}
while(!deque.isEmpty() && deque.peekLast() < nums[i]){//比较新push进来的元素,重复“带走”操作,维持队列单调性
deque.removeLast();
}
deque.addLast(nums[i]);
res[i-k+1]=deque.peekFirst();
}
return res;
}
}