我在代码随想录|写代码Day14之栈和队列-150. 逆波兰表达式求值,239. 滑动窗口最大值,347. 前 K 个高频元素

学习目标:

博主介绍: 27dCnc
专题 : 数据结构帮助小白快速入门
👍👍👍👍👍👍👍👍👍👍👍👍
☆*: .。. o(≧▽≦)o .。.:*☆

主题: 栈

今日份打卡
77

  • 代码随想录-栈

学习内容:

  1. 逆波兰表达式求值
  2. 滑动窗口最大值
  3. 前 K 个高频元素
  4. 栈与队列总结

150. 逆波兰表达式求值

经典题目
逆波兰表达式求值

图解

11111

栈与递归之间在某种程度上是可以转换的,其实逆波兰表达式相当于是二叉树中的后序遍历。

  • 遇到数字进栈
  • 遇到运算符进行加减运算
  • 将运算结果放入栈中
  • 直到将字符串最后一个元素遍历后栈中仅剩一个元素后返回答案

代码

class Solution {
public:
    int evalRPN(vector<string>& s) {
        stack<int>st;
        for(int i=0;i < s.size();i++) {
            if(st.empty() || (s[i].compare("+")  && s[i].compare("-") && s[i].compare("*") && s[i].compare("/"))) {
                int num = atoi(s[i].c_str());
                st.push(num);
            } else {
                int x = st.top();
                st.pop();
                int y = st.top();
                st.pop();
                switch(s[i][0]) {
                    case '+' : st.push(x+y);break;
                    case '-' : st.push(y-x);break;
                    case '*' : st.push(x*y);break;
                    case '/' : st.push(y/x); break;
                }
            }
        }
        return st.top();
    }
};

错误汇总:
不能如下:

if(st.empty() || (s[i] != ‘+’ && s[i] != ‘-’ && s[i] != ‘*’ && s[i] != ‘/’)) {
int num = atio(&s[i]);

也不可以如下:

if(st.empty() || (s[i].compare(‘+’) && s[i].compare(‘-’) && s[i].compare(‘*’) && s[i].compare(‘/’))) {
int num = atio(&s[i]);

正确如下:

if(st.empty() || (s[i].compare(“+”) && s[i].compare(“-”) && s[i].compare(“*”) && s[i].compare(“/”))) {
int num = atoi(s[i].c_str());

原因: compare 比较的是字符串 ''这样代表字符
atoi() 转化的是字符串而且是c语言风格所以要用 .c_str() 格式化
还有为什么要 s[i][0] 我也不太清楚

其他语言版本

Python

from operator import add, sub, mul

class Solution:
    op_map = {'+': add, '-': sub, '*': mul, '/': lambda x, y: int(x / y)}
    
    def evalRPN(self, tokens: List[str]) -> int:
        stack = []
        for token in tokens:
            if token not in {'+', '-', '*', '/'}:
                stack.append(int(token))
            else:
                op2 = stack.pop()
                op1 = stack.pop()
                stack.append(self.op_map[token](op1, op2))  # 第一个出来的在运算符后面
        return stack.pop()

Java

class Solution {
    public int evalRPN(String[] tokens) {
        Deque<Integer> stack = new LinkedList();
        for (String s : tokens) {
            if ("+".equals(s)) {        // leetcode 内置jdk的问题,不能使用==判断字符串是否相等
                stack.push(stack.pop() + stack.pop());      // 注意 - 和/ 需要特殊处理
            } else if ("-".equals(s)) {
                stack.push(-stack.pop() + stack.pop());
            } else if ("*".equals(s)) {
                stack.push(stack.pop() * stack.pop());
            } else if ("/".equals(s)) {
                int temp1 = stack.pop();
                int temp2 = stack.pop();
                stack.push(temp2 / temp1);
            } else {
                stack.push(Integer.valueOf(s));
            }
        }
        return stack.pop();
    }
}

GO

func evalRPN(tokens []string) int {
	stack := []int{}
	for _, token := range tokens {
		val, err := strconv.Atoi(token)
		if err == nil {
			stack = append(stack, val)
		} else {   // 如果err不为nil说明不是数字
			num1, num2 := stack[len(stack)-2], stack[(len(stack))-1]
			stack = stack[:len(stack)-2]
			switch token {
			case "+":
				stack = append(stack, num1+num2)
			case "-":
				stack = append(stack, num1-num2)
			case "*":
				stack = append(stack, num1*num2)
			case "/":
				stack = append(stack, num1/num2)
			}
		}
	}
	return stack[0]
}

239. 滑动窗口最大值

题目
11

代码

class MyQueue {
    public:
        deque<int> que;//使用deque来实现单调队列
        //每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出
        //同时pop之前判断队列是否为空
        void pop(int value) {
            if(!que.empty() && value == que.front()) {
                que.pop_front();
            }
        }
        //如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出
        void push(int value) {
            while(!que.empty() && value > que.back()) {
                que.pop_back();
            }
            que.push_back(value);
        }
        //查询当前队列里的最大值,直接返回队列前端也就是front就可以了
        int front() {
            return que.front();
        }
};

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        MyQueue que;
        vector<int> ans;
        for(int i = 0;i < k;i++) {
            que.push(nums[i]);
        }
        ans.push_back(que.front());//ans记录前K个元素最大值
        for(int i = k ;i < nums.size();i++) {
            que.pop(nums[i - k]);
            que.push(nums[i]);
            ans.push_back(que.front());
        }
        return ans;
    }
};

图解
3t

347. 前 K 个高频元素

题目
前 K 个高频元素
代码

class Solution {
public:
    //小顶堆
    class mycomparison {
    public:
        bool operator()(const pair<int,int>& lhs,const pair<int,int>& rhs){
            return lhs.second > rhs.second;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
        //统计元素出现频率
        unordered_map<int,int> map; //map<nums[i],对应出现次数
        for(int i = 0;i < nums.size();i++) {
            map[nums[i]]++;
        }
        //对频率排序
        //定义一个小顶堆,大小为k
        priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparison> pri_que;

        //用于固定大小为k的小顶堆,扫面所以频率数值
        for(unordered_map<int,int>::iterator it = map.begin();it != map.end();it++) {
            pri_que.push(*it);
            if (pri_que.size() > k) {
                pri_que.pop();
            }
        }
        vector<int> result(k);
        for(int i=k-1;i>=0;i--) {
            result[i] = pri_que.top().first;
            pri_que.pop();
        }
        return result;
    }
};

12

栈和队列总结

灵魂四问

  1. C++中stack,queue 是容器么?
  2. 我们使用的stack,queue是属于那个版本的STL?
  3. 我们使用的STL中stack,queue是如何实现的?
  4. stack,queue 提供迭代器来遍历空间么?

陷阱1:栈是容器适配器,底层容器使用不同的容器,导致栈内数据在内存中不一定是连续分布的。
陷阱2:缺省情况下,默认底层容器是deque,那么deque在内存中的数据分布是什么样的呢? 答案是:不连续的,下文也会提到deque。

栈经典题目

  1. 栈在系统中的应用
  2. 括号匹配问题
  3. 字符串去重问题
  4. 逆波兰表达式问题

队列的经典题目

  • 滑动窗口最大值问题
  • 求前 K 个高频元素

学习时间:

  • 周一至周五晚上 7 点—晚上9点
  • 周六上午 9 点-上午 11 点
  • 周日下午 3 点-下午 6 点

学习产出:

1.22

  • 技术笔记 2 遍
  • CSDN 技术博客 3 篇
  • 习的 vlog 视频 1 个

🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下博主~

本文作者:2c237c6

本文链接:https://www.cnblogs.com/27dCnc/p/18568656

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   2c237c6  阅读(4)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起