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 栈实现队列

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() {
        queue_1 = new LinkedList<Integer>();
        queue_2 = new LinkedList<Integer>();
    }
    
    public void push(int x) {
        // q_2 进
        queue_2.add(x);
        // q_1 全部移下来到 q_2
        while(!queue_1.isEmpty()){
            queue_2.add(queue_1.remove());
        }
        // q_2 全部又移到 q_1
        while(!queue_2.isEmpty()){
            queue_1.add(queue_2.remove());
        }
    }
    
    public int pop() {
        return queue_1.remove();
    }
    
    public int top() {
        return queue_1.peek();
    }
    
    public boolean empty() {
        return queue_1.isEmpty();
    }
}