11 阅读2分钟

# 1. 表达式求值

• 常见思路：中缀表达式转换成后缀表达式，然后再对后缀表达式求值

## 1.1 逆波兰表达式求值

``````class Solution {
public int evalRPN(String[] tokens) {
Stack<String> stack = new Stack<String>();

int n = tokens.length;    // 长度

for(int i=0;i<n;i++){
if(tokens[i].equals("+") || tokens[i].equals("-")
|| tokens[i].equals("*") || tokens[i].equals("/")){
// 如果是符号,出栈
int a = Integer.valueOf(stack.pop());
int b = Integer.valueOf(stack.pop());

if(tokens[i].equals("+")){
int c = a+b;
String str = String.valueOf(c);
stack.push(str);
}
else if(tokens[i].equals("-")){
int c = b-a;
String str = String.valueOf(c);
stack.push(str);
}
else if(tokens[i].equals("*")){
int c = b*a;
String str = String.valueOf(c);
stack.push(str);
}
else if(tokens[i].equals("/")){
int c = b/a;
String str = String.valueOf(c);
stack.push(str);
}
}else{
stack.push(tokens[i]);
}
}

int res = Integer.valueOf(stack.pop());

return res;
}
}
``````

## 1.2 基本计算器

``````class Solution {
public int calculate(String s) {
Stack<Integer> ops = new Stack<Integer>();
ops.push(1);
int sign = 1;   // 当前符号

int ret = 0;
int n = s.length();
int i = 0;

while(i < n){
if(s.charAt(i) == ' '){
i++;
}
else if(s.charAt(i) == '+'){
sign = ops.peek();
i++;
}
else if(s.charAt(i) == '-'){
sign = -ops.peek();
i++;
}
else if(s.charAt(i) == '('){
ops.push(sign);
i++;
}
else if(s.charAt(i) == ')'){
ops.pop();
i++;
}
else{
int num = 0;
while(i<n && s.charAt(i)<='9' && s.charAt(i)>='0'){
num = num*10 + s.charAt(i) - '0';
i++;
}
ret += sign*num;
}
}

return ret;
}
}
``````

## 1.3 基本计算器 II

``````class Solution {
public int calculate(String s) {
Stack<Integer> stack = new Stack<Integer>();
char preSign = '+';
int n = s.length();
int num = 0;

for(int i=0;i<n;i++){
if('0'<=s.charAt(i) && s.charAt(i)<='9'){
// 如果是数字
num = num*10 + s.charAt(i) - '0';
}
if(!Character.isDigit(s.charAt(i)) && s.charAt(i)!=' ' || i==n-1){
switch(preSign){
case '+':
stack.push(num);
break;
case '-':
stack.push(-num);
break;
case '*':
stack.push(stack.pop() * num);
break;
default:
stack.push(stack.pop() / num);
}
preSign = s.charAt(i);
num = 0;
}
}

int ans = 0;
while(!stack.isEmpty()) ans += stack.pop();

return ans;
}
}
``````

# 2. 单调队列

## 2.1 下一个更大元素 II

``````class Solution {
public int[] nextGreaterElements(int[] nums) {
int n = nums.length;
Stack<Integer> stack = new Stack<Integer>();
int[] res = new int[n];

for(int i=2*n-1;i>=0;i--){
while(!stack.isEmpty() && nums[i%n]>=stack.peek()){
stack.pop();
}
if(stack.isEmpty()) res[i%n] = -1;
else res[i%n] = stack.peek();

stack.push(nums[i%n]);
}

return res;
}
}
``````

## 3.1 用栈实现队列

``````class MyQueue {
Stack<Integer> stack_1;  // 用来入栈
Stack<Integer> stack_2;  // 用来出栈

public MyQueue() {
stack_1 = new Stack<Integer>();
stack_2 = new Stack<Integer>();
}

public void push(int x) {
stack_1.push(x);
}

public int pop() {
if(stack_2.isEmpty()) while(!stack_1.isEmpty()) stack_2.push(stack_1.pop());
return stack_2.pop();
}

public int peek() {
if(stack_2.isEmpty()) while(!stack_1.isEmpty()) stack_2.push(stack_1.pop());
return stack_2.peek();
}

public boolean empty() {
return stack_2.isEmpty()&&stack_1.isEmpty();
}
}
``````

## 3.2 用队列实现栈

``````class MyStack {
Queue<Integer> queue_1;
Queue<Integer> queue_2;

public MyStack() {
}

public void push(int x) {
// q_2 进
// q_1 全部移下来到 q_2
while(!queue_1.isEmpty()){
}
// q_2 全部又移到 q_1
while(!queue_2.isEmpty()){
}
}

public int pop() {
return queue_1.remove();
}

public int top() {
return queue_1.peek();
}

public boolean empty() {
return queue_1.isEmpty();
}
}
``````