代码随想录算法训练营第十三天|150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素

1、逆波兰表达式求值

通过改变运算符与操作数的相对位置,我们分别得到前序表达式和后序表达式。前序表达式要求所有的运算符出现在它所作用的两个操作数之前,后序表达式则相反。

例子:
请添加图片描述

逆波兰表达式也就是后序表达式。

题目链接/文章讲解/视频讲解:
https://programmercarl.com/0150.%E9%80%86%E6%B3%A2%E5%85%B0%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B1%82%E5%80%BC.html

题目:根据 逆波兰表示法,求表达式的值。
有效的运算符包括 + , - , * , / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

思路:
1、将数字都压入栈中;
2、当遇到操作符,就将栈顶的两个数字提出计算,注意先提出的在操作符的右边,后提出的在操作符左边;
3、将计算结果重新压入栈中,最后遍历完,栈顶就是计算结果。

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        int num1,num2;
        for (String s: tokens) {
            if ("+".equals(s)) {
                num1 = stack.pop();
                num2 = stack.pop();
                stack.push(num1 + num2);
            } else if ("-".equals(s)) {
                num2 = stack.pop();
                num1 = stack.pop();
                stack.push(num1 - num2);
            } else if ("*".equals(s)) {
                num1 = stack.pop();
                num2 = stack.pop();
                stack.push(num1 * num2);
            } else if ("/".equals(s)) {
                num2 = stack.pop();
                num1 = stack.pop();
                stack.push(num1 / num2);
            } else {
                stack.push(Integer.valueOf(s));
            }
        }
        return stack.pop();
    }
}

2、滑动窗口最大值

题目链接/文章讲解/视频讲解:
https://programmercarl.com/0239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC.html

题目:给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

思路:
1、自定义一个单调栈,维持栈中是单调的,栈顶一直是最大值
(1)入栈:如果非空栈且栈中有小于当前值的值,就从栈尾删除,保证栈中单调减;
(2)出栈:如果非空栈,且要出栈的是栈顶最大值,则出栈;因为在出栈过程中,如果不是栈中的最大值,可能在最大值入栈时已经被移除;
(3)最大值:栈顶值。

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

    public void poll(int val) {
        if (!deque.isEmpty() && val == deque.peek()) {
            deque.poll();
        }
    }

    public void offer(int val) {
        while (!deque.isEmpty() && deque.peekLast() < val) {
            deque.pollLast();
        }
        deque.offer(val);
    }

    public int getMax() {
        return deque.peek();
    }
}

2、遍历数组,在滑动窗口的时候先出栈,再入栈,最后取出窗口内最大值。

	public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums.length == 1) {
            return nums;
        }
        MyQueue myque = new MyQueue();
        for (int i = 0; i < k; i++) {
            myque.offer(nums[i]);
        }
        int[] res = new int[nums.length - k + 1];
        res[0] = myque.getMax();
        for (int index = k; index < nums.length; index++) {
            myque.poll(nums[index - k]);
            myque.offer(nums[index]);
            res[index - k + 1] = myque.getMax();
        }
        return res;
    }

3、前 K 个高频元素

题目链接/文章讲解/视频讲解:
https://programmercarl.com/0347.%E5%89%8DK%E4%B8%AA%E9%AB%98%E9%A2%91%E5%85%83%E7%B4%A0.html

题目:给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

思路:
1、要统计元素出现频率,这里使用Map容器,key为数组值,value为出现次数

		Map<Integer, Integer> map = new HashMap<>();
        for (int num: nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }

2、对频率排序,考虑优先队列,用大根堆,存储的前k个元素就是我们要的答案;

PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2)->pair2[1]-pair1[1]);
for (Map.Entry<Integer, Integer> entry: map.entrySet()) {
	pq.add(new int[]{entry.getKey(), entry.getValue()});
}

3、找出前K个高频元素

int[] res = new int[k];
for (int i = 0; i < k; i++) {
	res[i] = pq.poll()[0];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值