第一遍写的错误点:
1. 不会处理运算。怎么压栈倒是学的很快,拿出来发现是字符串时就不会处理了。
op = {'+': add, '-': sub, '*': mul, '/': div}
其中add, sub, mul都是operator库里的,from operator impact add,sub,mul。而div是自己定义的方法。
2. 栈的初始化是stack = [],不要记错了。
3. 先取出来的a1是后面的值,所以temp = self.op[i](a2,a1)。这个bug找了半天才意识到。
4. “除法结果总是向零截断”,这意味着当x * y < 0时,应该先取绝对值运算除法,然后再给除法结果加负号。这是因为原本的//是向下取整,x * y < 0时会再往小的方向取整。
5. 取绝对值:abs()
代码随想录说有点难,一刷可以只求理解思路。
看完题目首先是觉得想不到要怎么用栈或者队列解决。说到滑动窗口我就想双指针,但是这题并不适合。文心回答:
如何判断滑动窗口问题是否适合用双指针?
-
操作复杂程度:如果窗口内的操作相对简单,比如只是简单的计数、求和或比较,使用双指针;如果窗口内的操作涉及到复杂的查询(如查找最大值、最小值、中位数等),或者需要维护有序性,那么可能需要使用特定的数据结构。
-
窗口大小是否固定:如果窗口大小固定,那么双指针是一个很好的选择;如果窗口大小可变,可能需要双指针结合其他数据结构来优化性能。
算法关键点在于,维护一个deque类型的双头队列作为滑动窗口。
(push)读到了更大的数就把双头队列前端的几个数都弹出。(pop)而滑动窗口时,需要判断窗口前面要移除的那个数是不是早就不在队列里了。所以要判断value == que.front()时才把que前面这个数字移除掉。
重点:区分出口入口。滑动窗口最大值在队列出口,维护在队列入口。后面就慢慢明白了!
算法:首先统计频率,然后对频率排序。→优先级队列→披着队列外皮的堆。
堆是一颗顺序存储的完全二叉树。
每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆;
每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大根堆。
例如,一个大根堆,如果新加了一个节点比父母节点大,就和上面的父母节点交换位置,直到遇到比他大的父母节点。
本题用小顶堆,因为我们求频率最高的,堆的弹出是弹头节点(每次把最小的弹出去,新加的放头节点,然后再调整)。看懂了!
栈与队列的总结:栈已经so easy了,队列还需多多掌握。