代码随想录刷题Day15

82 阅读2分钟

150. 逆波兰表达式求值

  • 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];
    }
}

239. 滑动窗口最大值

  • 单调队列,超级妙 image.png

配合leetcode.cn/problems/sl… 的图

和卡尔的视频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;
    }
}