1.用两个栈实现一个队列
问题描述:
用两个栈实现一个队列。队列的声明如下:实现它的两个函数 appendChild 和 deleteChild,分别在队列尾部插入结点和在队列头部删除结点的功能。
思路:
往队列中插入元素:放入 stack1;
从队列中删除元素:
- 当 stack2 不为空时,在 stack2 栈顶的元素弹出,作为被删除元素;
- 当 stack2 为空,把 stack1 的元素依次 pop 再 push 到stack2 中,然后在 stack2 栈顶的元素弹出,作为被删除元素。
代码:
|
|
2.用两个队列实现一个栈
思路:
- 入队列时,
代码:
|
|
3.包含 min 函数的栈
问题描述:
定义栈的数据结构,在该类型中实现一个能够得到栈的最小元素的 min 函数。在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
思路:
再用一个辅助栈。
当向栈中添加元素时,与辅助栈中元素比较:
- 如果小,向辅助栈中添加该元素,
- 否则向辅助栈中再次添加辅助栈栈顶元素。
代码:
|
|
4.栈的压入、弹出序列
问题描述:
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。
例如:
序列 1、2、3、4、5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列。但4、3、5、1、2就不可能是该压栈序列的弹出序列。
思路:
建立一个辅助栈,把序列一的数字依次压入辅助栈,并按照序列二的顺序依次从该栈中弹出数字。
遍历序列一,判断序列二是不是栈的弹出序列:
- 向栈中压入序列一的数值;
- 如果下一个要弹出的数字刚好是栈顶数字,那么直接弹出;
- 如果下一个弹出的数字不在栈顶,我们把序列一中还没有入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶为止。
- 如果所有的数字都压入栈了,仍然没有找到下一个要弹出的数字,那么该序列不是一个弹出序列。
- 反之,如果是弹出序列,则辅助栈最后应为空。
代码:
|
|
5.滑动窗口的最大值
问题描述:
给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。
例如:
如果给定数组 {2,3,4,2,6,2,5,1} 及滑动窗口的大小3,那么一共存在 6 个滑动窗口,她们的最大值分别是{4,4,6,6,6,5}。
思路:
- 把有可能成为滑动窗口最大值的数值 存储到一个双端队列 deque 中。
- 为了知道一个数字是否还包括在当前的滑动窗口中,应该在队列里存储数组元素的下标,而非数值本身。当一个数字的下标与当前处理的数字的下标之差大于等于滑动窗口大小时,这个数字就可以从滑动窗口中滑出了。
处理过程:
- 如果新来的数值比队列尾部的数小,那就追加到后面,因为它可能在前面的最大值滑出窗口后成为最大值;
- 如果新来的数值比队列尾部的数大,那就删掉尾部,再追加到后面,循环下去直到小于;
- 如果追加的值的索引与队列头部的值的索引之差,超过窗口大小,那就删掉头部的值;
- 这样每次队列头部都是最大的那个。
代码:
|
|