day10逆波兰表达式求值&滑动窗口求最大值

        今天的题目比较难,用的都是没怎么见过的数据结构。

1.力扣150

        逆波兰表达式实际上是计算器求解结果的常用模式,首先是将计算式转为前缀、中缀或后缀表达式,然后根据这个表达式进行计算结果,B站尚硅谷的数据结构课程中有讲解,我利用这个逻辑做过网页版的计算器。

        本题是直接求逆波兰表达式的值比较简单,利用栈结构实现,在遍历数组的过程中,碰到数字就存进栈中,碰到操作符就取出栈顶的两个元素,进行操作后并存入栈结构中,最终取出栈中剩余元素。

                ​​​​​​​        

解题步骤:

  • 定义一个栈结构。然后遍历数组
  • 若碰到数字就存入栈中;若碰到操作符就取出,计算出数值后存入栈中。
  • 遍历结束后,取出元素。

代码实现:

    public int evalRPN(String[] tokens) {
        //定义栈
        Stack<Integer> stack = new Stack<>();
        //遍历元素
        for(int i=0;i<tokens.length;i++){
            String s = tokens[i];
            //判断是否为操作符
            if("+".equals(s)||"-".equals(s)||"*".equals(s)||"/".equals(s)){
                //因为栈是逆序的,所以需要调换取出的顺序
                Integer num2 = stack.pop();
                Integer num1 = stack.pop();
                switch (s){
                    case "+":
                        stack.push(num1+num2);
                        break;
                    case "-":
                        stack.push(num1-num2);
                        break;
                    case "*":
                        stack.push(num1*num2);
                        break;
                    case "/":
                        stack.push(num1/num2);
                        break;
                }
            }else{
                //不是操作符就存入栈中,因为是字符串,所以需要转型
                stack.push(Integer.valueOf(s));
            }
        }
        return stack.pop();
    }

2.力扣239

        本题难度较大,利用单调队列实现,也就是保证队列中元素的单调性的一种队列。首先我们要自定义一个类,MyQueue来实现次种结构,里面有三种方法:poll(取出元素),add(存入元素),peek(取出队首元素),下面来单独说下具体的代码实现:

  • 首先我们规定这种元素是在入队列的时候会判断这个队列的尾元素是否比这个元素小,若小的话就会移除这个元素,然后讲这个元素入队列
  • poll:我们在弹出元素的时候,有两种情况;一种是小于队首元素(这个时候就不需要移除),一种是等于队首元素,此时需要我们手动移除元素
  • add:这里添加需要判断队列尾元素和待插入数的大小,根据上面的规定,我们需要循环查找的操作,待插入的位置,也就是一直移除元素直至合适的位置。
  • peek:直接返回队首元素

        ​​​​​​​

代码实现:

class MyQueue {
    Deque<Integer> deque = new LinkedList<>();

    //弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出
    //同时判断队列当前是否为空
    public void pop(int val){
        if(!deque.isEmpty()&&val==deque.peek()){
            deque.pollFirst();
        }
    }

    //添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出
    //保证队列元素单调递减
    //比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2
    public void add(int val){
        while(!deque.isEmpty()&&val>deque.peekLast()){
            deque.pollLast();
        }
        deque.addLast(val);
    }
    //队列队顶元素始终为最大值
    public int peek(){
        return deque.peekFirst();
    }
}

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums.length==1){
            return nums;
        }
        //存放结果数组
        int index = 0;
        int[] arr = new int[nums.length-k+1];
        //定义数据结构
        MyQueue myQueue = new MyQueue();
        for(int i=0;i<k;i++){
            myQueue.add(nums[i]);
        }
        arr[index++] = myQueue.peek();

        //遍历整个数组
        for(int i= k;i<nums.length;i++){
            myQueue.pop(nums[i-k]);
            myQueue.add(nums[i]);
            arr[index++] = myQueue.peek();
        }
        return arr;
    }
    
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值