1 栈与队列
1.1 双端队列(Deque: Double-End Queue):相当于一个Stack和Queue的结合
1.2 优先队列(PriorityQueue )
底层具体实现的数据结构较为多样和复杂:heap(堆)、bst、treap
1.3 特点与时间复杂度
- Stack:先入后出;添加、删除皆为 O(1)
- Queue:先入先出;添加、删除皆为 O(1)
- Deque:两端可以进出; 插入和删除都是 O(1) 操作
- PriorityQueue :插入O(1),取出操作O(log n)-按照元素的优先级取出
1.4 常用操作(java)
Stack进栈与出栈
-
boolean empty()
测试此堆栈是否为空。 -
E peek()
查看此堆栈顶部的对象。 -
E pop()
出栈,并将该对象作为此函数的值返回。 -
E push(E item)
入栈 -
int search(Object o)
返回一个对象在此堆栈上的基于1的位置。
Queue -
boolean add(E e)
将指定的元素插入到此队列中,如果不违反容量限制,成功返回 true ,如果满了,则抛出 IllegalStateException 。 -
E element()
检索这个队列的头。 -
boolean offer(E e)
如果在不违反容量限制的情况下立即执行,则将指定的元素插入到此队列中。 -
E peek()
检索但不删除此队列的头,如果此队列为空,则返回 null 。 -
E poll()
检索并删除此队列的头部,如果此队列为空,则返回 null 。 -
E remove(
) 检索并删除此队列的头。
Deque
1.5 代码的实现
1)python
2 算法题解
2.1 stack
要思考这类题目为什么要用stack来解决
如果有最近相关性的话,会用栈来解决
- 如果一个工程要解决的问题是从外向内或从内向外逐渐扩散就需要stack
- 先来后到就用queue
- 滑动窗口问题使用队列
1)柱状图中最大的矩形
维护一个栈
- 通过入栈从小到大的顺序来确定一根柱子的左右边界
- 先入栈一个-1占位,一根柱子能构成的最大面积的公式为 :
(i - st.peek() - 1) * st.pop()
- 如图2入栈,1比2小,弹出1,就可以确定2的边界就是在1这根柱子,第一个为2的柱子所能构成的最大面积就为2*1
- 之后继续入栈:1-5-6 遇到第二个2时出栈6 这时 6这根柱子左右边界确定了,能构成的最大面积为6*1
- 2还是比5小,又弹出5,此时5的左右边界确定,最大面积5*2
- 继续入栈1-2-3 入栈到此数组就遍历完了,最后依次弹出栈中剩余的顺序柱子3-2-1,并计算其面积大小
- 最终max_a rea中保存的面积就为该柱状图中能勾勒出的最大面积
*/
// @lc code=start
public class Solution {
public int largestRectangleArea(int[] heights) {
Stack<Integer> st = new Stack<>();
st.push(-1); // 先入栈一个-1
int max_area = 0; // 设置最大面积变量
for (int i = 0; i < heights.length; ++i) {
// 当栈顶部不为-1,并且大于等于下一柱子的高度时出栈,并计算面积
while (st.peek() != -1 && heights[st.peek()] >= heights[i]) {
// 计算出栈柱子的最大面积
max_area = Math.max(max_area, heights[st.pop()] * (i - st.peek() - 1));
}
st.push(i); // 入栈i
}
// 出栈并计算栈内剩余的顺序排列的柱子能够成的面积
while (st.peek() != -1) {
max_area = Math.max(max_area, heights[st.pop()] * (heights.length - st.peek() - 1));
}
return max_area;
}
}