题目
面试题 03.05. 栈排序 - 力扣(LeetCode)
栈排序。 编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:push
、pop
、peek
和 isEmpty
。当栈为空时,peek
返回 -1。
示例1:
输入:
输出:
示例2:
输入:
输出:
说明:
- 栈中的元素数目在[0, 5000]范围内。
分析
栈是先进后出,对栈进行排序,将这个栈命名为数据栈A,使最小元素位于数据栈的栈顶,也就意味着栈底是最大的元素,先放进去的是最大的元素,然后按顺序递减到最小元素。
题目说可以使用一个辅助栈来实现,命名为辅助栈B,那么辅助栈内的元素存储数据的时候,数据大小顺序应该是反过来,也就是最大元素位于辅助栈B的栈顶。 这样从辅助栈B迁移数据到数据栈A的时候,刚好满足题目需求。
排序的时候,使用前后堆叠的方式进行即可,比如说,以一组排好顺序的数据作为一组,如果比这组数据最大的大,就放在大的一端,比这组数据的最小的数据小,就放在小的一端。
比如类似数据如下:
- 为了使数据栈A最小元素位于栈顶,则必须让数据A中小的元素放在辅助栈B的栈底。 从数据栈A取出 5 放入辅助栈B
- 继续比较 数据栈A的数据 7 比 辅助栈B的栈顶5还大,将大的数据 7 放入 辅助栈B。
- 继续比较 数据栈A,发现 1 比辅助栈B栈顶7小,则说明当前不是合适的存放位置,将 1 存放入临时变量data_tmp中,然后将数据栈A的1释放掉
- 再将辅助栈B数据重新依次和临时变量data_tmp进行比较,如果辅助栈B栈顶数据大于临时变量data_tmp,就重新压回数据栈A中,如果小于,则将临时变量data_tmp压入辅助栈B,然后清空辅助变量data_tmp。
- 然后可以将
5 7
重新压回辅助栈B, 这时候相当于辅助栈B的 5 7
数据作为了一组有序数据进行了移动,后续循环进行2~4进行数据分组堆叠操作操作即可完成辅助栈排序。
- 完成辅助栈B的排序后,将辅助栈数据B重新压入数据栈A即可得到结果
只用一个栈的代码规则汇总
- 构建临时变量data_tmp和辅助栈B
- 如果临时变量data_tmp没有数据,则遍历数据栈A,如果数据栈A栈顶比辅助栈B顶大,则将数据栈A数据压入辅助栈B,同时释放数据栈A这个数据,否则放入临时变量data_tmp,同时释放数据栈A的这个数据。
- 如果临时变量data_tmp有数据,则比较临时变量data_tmp是否大于辅助栈B栈顶,如果大于,则将临时变量data_tmp放入辅助栈B栈顶,否则将辅助栈B栈顶数据压入数据栈A中。
- 重复操作2和3,直到数据栈A数据清零,且临时变量data_tmp中没有数据,然后重新将辅助栈B数据压入数据栈A,得到的即为要求结果。
使用共两个栈保存数据
如果能使用两个栈进行数据保存的话,那么只需要维护两个栈,一个栈总是顺序排序,另一个栈总是逆序排序,
在插入数据的时候动态调整插入数据位置,就能减少在push操作中重复传递数据的次数,进而能提高性能。
通过例子来说明, 现有数据data 8 9 2 3 1 7 5
:
- 始终保证 数据栈 data_stackA 的数据比 辅助栈 data_tmp 的大,并将data_stackA作为最小栈,data_tmp 作为最大栈。先添加 5 入数据栈 data_stackA
- 继续添加 7 , 因为 7 比 data_stackA 栈顶数据5大,又因为 data_stackA 数据需要大于 data_tmp ,因此要将 data_stackA 数据压入data_tmp,然后再继续把 7 压入 data_stackA。
- 继续重复 1~2 操作,直到存入所有数据
- 在peek取出数据或pop操作的时候,要将临时最大栈data_tmp 数据压入数据最小栈data_stackA,因为data_stackA数据始终比data_tmp大,因此最后data_stackA 数据为最小栈。
两个栈编码规则
- push操作中,如果插入数据data始终比最小栈data_stackA大,则将data_stackA数据压入data_tmp,然后将data压入data_stackA。
- push操作中,如果插入数据data比最小栈data_stackA小,但是比最大栈data_tmp大,则直接将data压入data_stackA。
- push操作中,如果插入数据data始终比最大栈data_tmp小,则将data_tmp数据压入data_stackA,然后将data压入data_stackA。
- seek或pop操作中,如果最大栈data_tmp中存在数据,则将data_tmp数据压入data_stackA。
- 将数据最小栈data_stackA 定义为
m_min_stack
, 将辅助最大栈data_tmp定义为 m_max_stack
。
代码
只用一个栈排序的代码
数据栈+辅助栈排序代码
*****